Home | History | Annotate | Download | only in optimizing
      1 /*
      2  * Copyright (C) 2014 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 
     17 #ifndef ART_COMPILER_OPTIMIZING_GRAPH_CHECKER_H_
     18 #define ART_COMPILER_OPTIMIZING_GRAPH_CHECKER_H_
     19 
     20 #include <ostream>
     21 
     22 #include "base/arena_bit_vector.h"
     23 #include "base/bit_vector-inl.h"
     24 #include "base/scoped_arena_allocator.h"
     25 #include "nodes.h"
     26 
     27 namespace art {
     28 
     29 // A control-flow graph visitor performing various checks.
     30 class GraphChecker : public HGraphDelegateVisitor {
     31  public:
     32   explicit GraphChecker(HGraph* graph, const char* dump_prefix = "art::GraphChecker: ")
     33     : HGraphDelegateVisitor(graph),
     34       errors_(graph->GetAllocator()->Adapter(kArenaAllocGraphChecker)),
     35       dump_prefix_(dump_prefix),
     36       allocator_(graph->GetArenaStack()),
     37       seen_ids_(&allocator_, graph->GetCurrentInstructionId(), false, kArenaAllocGraphChecker) {
     38     seen_ids_.ClearAllBits();
     39   }
     40 
     41   // Check the whole graph. The pass_change parameter indicates whether changes
     42   // may have occurred during the just executed pass. The default value is
     43   // conservatively "true" (something may have changed). The last_size parameter
     44   // and return value pass along the observed graph sizes.
     45   size_t Run(bool pass_change = true, size_t last_size = 0);
     46 
     47   void VisitBasicBlock(HBasicBlock* block) override;
     48 
     49   void VisitInstruction(HInstruction* instruction) override;
     50   void VisitPhi(HPhi* phi) override;
     51 
     52   void VisitBinaryOperation(HBinaryOperation* op) override;
     53   void VisitBooleanNot(HBooleanNot* instruction) override;
     54   void VisitBoundType(HBoundType* instruction) override;
     55   void VisitBoundsCheck(HBoundsCheck* check) override;
     56   void VisitCheckCast(HCheckCast* check) override;
     57   void VisitCondition(HCondition* op) override;
     58   void VisitConstant(HConstant* instruction) override;
     59   void VisitDeoptimize(HDeoptimize* instruction) override;
     60   void VisitIf(HIf* instruction) override;
     61   void VisitInstanceOf(HInstanceOf* check) override;
     62   void VisitInvokeStaticOrDirect(HInvokeStaticOrDirect* invoke) override;
     63   void VisitLoadException(HLoadException* load) override;
     64   void VisitNeg(HNeg* instruction) override;
     65   void VisitPackedSwitch(HPackedSwitch* instruction) override;
     66   void VisitReturn(HReturn* ret) override;
     67   void VisitReturnVoid(HReturnVoid* ret) override;
     68   void VisitSelect(HSelect* instruction) override;
     69   void VisitTryBoundary(HTryBoundary* try_boundary) override;
     70   void VisitTypeConversion(HTypeConversion* instruction) override;
     71 
     72   void CheckTypeCheckBitstringInput(HTypeCheckInstruction* check,
     73                                     size_t input_pos,
     74                                     bool check_value,
     75                                     uint32_t expected_value,
     76                                     const char* name);
     77   void HandleTypeCheckInstruction(HTypeCheckInstruction* instruction);
     78   void HandleLoop(HBasicBlock* loop_header);
     79   void HandleBooleanInput(HInstruction* instruction, size_t input_index);
     80 
     81   // Was the last visit of the graph valid?
     82   bool IsValid() const {
     83     return errors_.empty();
     84   }
     85 
     86   // Get the list of detected errors.
     87   const ArenaVector<std::string>& GetErrors() const {
     88     return errors_;
     89   }
     90 
     91   // Print detected errors on output stream `os`.
     92   void Dump(std::ostream& os) const {
     93     for (size_t i = 0, e = errors_.size(); i < e; ++i) {
     94       os << dump_prefix_ << errors_[i] << std::endl;
     95     }
     96   }
     97 
     98  protected:
     99   // Report a new error.
    100   void AddError(const std::string& error) {
    101     errors_.push_back(error);
    102   }
    103 
    104   // The block currently visited.
    105   HBasicBlock* current_block_ = nullptr;
    106   // Errors encountered while checking the graph.
    107   ArenaVector<std::string> errors_;
    108 
    109  private:
    110   // String displayed before dumped errors.
    111   const char* const dump_prefix_;
    112   ScopedArenaAllocator allocator_;
    113   ArenaBitVector seen_ids_;
    114 
    115   DISALLOW_COPY_AND_ASSIGN(GraphChecker);
    116 };
    117 
    118 }  // namespace art
    119 
    120 #endif  // ART_COMPILER_OPTIMIZING_GRAPH_CHECKER_H_
    121