16447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea/*
26447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * Copyright (C) 2011 The Android Open Source Project
36447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea *
46447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * Licensed under the Apache License, Version 2.0 (the "License");
56447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * you may not use this file except in compliance with the License.
66447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * You may obtain a copy of the License at
76447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea *
86447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea *      http://www.apache.org/licenses/LICENSE-2.0
96447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea *
106447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * Unless required by applicable law or agreed to in writing, software
116447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * distributed under the License is distributed on an "AS IS" BASIS,
126447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
136447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * See the License for the specific language governing permissions and
146447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * limitations under the License.
156447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea */
166447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea
176447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea#ifndef ART_COMPILER_SEA_IR_TYPES_TYPE_INFERENCE_VISITOR_H_
186447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea#define ART_COMPILER_SEA_IR_TYPES_TYPE_INFERENCE_VISITOR_H_
196447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea
206447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea
216447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea#include "dex_file-inl.h"
22bfaf44fa3366955a2bacb2c38c79b53df2434582Dragos Sbirlea#include "sea_ir/ir/visitor.h"
236447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea#include "sea_ir/types/types.h"
246447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea
256447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleanamespace sea_ir {
266447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea
276447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea// The TypeInferenceVisitor visits each instruction and computes its type taking into account
286447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea//   the current type of the operands. The type is stored in the visitor.
296447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea// We may be better off by using a separate visitor type hierarchy that has return values
306447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea//   or that passes data as parameters, than to use fields to store information that should
316447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea//   in fact be returned after visiting each element. Ideally, I would prefer to use templates
326447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea//   to specify the returned value type, but I am not aware of a possible implementation
336447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea//   that does not horribly duplicate the visitor infrastructure code (version 1: no return value,
346447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea//   version 2: with template return value).
356447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleaclass TypeInferenceVisitor: public IRVisitor {
366447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea public:
376547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  TypeInferenceVisitor(SeaGraph* graph, TypeData* type_data,
386547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea      art::verifier::RegTypeCache* types):
396547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea    graph_(graph), type_data_(type_data), type_cache_(types), crt_type_() {
406447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  }
416447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  // There are no type related actions to be performed on these classes.
426447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  void Initialize(SeaGraph* graph) { }
4390af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea  void Visit(SeaGraph* graph);
446447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  void Visit(Region* region) { }
456447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea
466547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  void Visit(PhiInstructionNode* instruction);
477b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea  void Visit(SignatureNode* parameter);
486447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  void Visit(InstructionNode* instruction) { }
496547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  void Visit(UnnamedConstInstructionNode* instruction);
506447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  void Visit(ConstInstructionNode* instruction) { }
516447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  void Visit(ReturnInstructionNode* instruction) { }
526447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  void Visit(IfNeInstructionNode* instruction) { }
536547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  void Visit(MoveResultInstructionNode* instruction);
546547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  void Visit(InvokeStaticInstructionNode* instruction);
556547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  void Visit(AddIntInstructionNode* instruction);
566447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  void Visit(GotoInstructionNode* instruction) { }
576447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  void Visit(IfEqzInstructionNode* instruction) { }
586447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea
596547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  const Type* MergeTypes(std::vector<const Type*>& types) const;
606547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  const Type* MergeTypes(const Type* t1, const Type* t2) const;
61423fb4d70f2ac36bf9f630146b4150771a8e7e76Dragos Sbirlea  std::vector<const Type*> GetOperandTypes(InstructionNode* instruction) const;
627b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea  const Type* GetType() {
636447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea    // TODO: Currently multiple defined types are not supported.
6402e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier    if (!crt_type_.empty()) {
657b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea      const Type* single_type = crt_type_.at(0);
667b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea      crt_type_.clear();
677b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea      return single_type;
687b89bc0d1e73ae5a4265f93bb5497019b1a9bf17Dragos Sbirlea    }
696447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea    return NULL;
706447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  }
716447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea
726447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea protected:
736447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  const SeaGraph* const graph_;
746547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea  TypeData* type_data_;
756447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  art::verifier::RegTypeCache* type_cache_;
766447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea  std::vector<const Type*> crt_type_;             // Stored temporarily between two calls to Visit.
776447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea};
786447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea
796447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea}  // namespace sea_ir
806447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea
816447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea#endif  // ART_COMPILER_SEA_IR_TYPES_TYPE_INFERENCE_VISITOR_H_
82