16447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea/* 26447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea * Copyright (C) 2013 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 176547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea#include "scoped_thread_state_change.h" 186447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea#include "sea_ir/types/type_inference_visitor.h" 196447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea#include "sea_ir/types/type_inference.h" 20bfaf44fa3366955a2bacb2c38c79b53df2434582Dragos Sbirlea#include "sea_ir/ir/sea.h" 216447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 226447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleanamespace sea_ir { 236447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 2490af14d2743614e3e1453984b14258a6f145501dDragos Sbirleavoid TypeInferenceVisitor::Visit(SeaGraph* graph) { 2590af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea FunctionTypeInfo fti(graph_, type_cache_); 2690af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea const Type* return_type = fti.GetReturnValueType(); 2790af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea crt_type_.push_back(return_type); 2890af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea} 2990af14d2743614e3e1453984b14258a6f145501dDragos Sbirlea 306447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirleavoid TypeInferenceVisitor::Visit(SignatureNode* parameter) { 316447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea FunctionTypeInfo fti(graph_, type_cache_); 326447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea std::vector<const Type*> arguments = fti.GetDeclaredArgumentTypes(); 336447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea DCHECK_LT(parameter->GetPositionInSignature(), arguments.size()) 346447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea << "Signature node position not present in signature."; 356447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea crt_type_.push_back(arguments.at(parameter->GetPositionInSignature())); 366447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea} 376447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea 386547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirleavoid TypeInferenceVisitor::Visit(UnnamedConstInstructionNode* instruction) { 396547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea crt_type_.push_back(&type_cache_->Integer()); 406547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea} 416547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea 426547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirleavoid TypeInferenceVisitor::Visit(PhiInstructionNode* instruction) { 436547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea std::vector<const Type*> types_to_merge = GetOperandTypes(instruction); 446547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea const Type* result_type = MergeTypes(types_to_merge); 456547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea crt_type_.push_back(result_type); 466547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea} 476547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea 486547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirleavoid TypeInferenceVisitor::Visit(AddIntInstructionNode* instruction) { 496547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea std::vector<const Type*> operand_types = GetOperandTypes(instruction); 506547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea for (std::vector<const Type*>::const_iterator cit = operand_types.begin(); 516547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea cit != operand_types.end(); cit++) { 526547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea if (*cit != NULL) { 536547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea DCHECK((*cit)->IsInteger()); 546547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea } 556547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea } 566547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea crt_type_.push_back(&type_cache_->Integer()); 576547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea} 586547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea 596547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirleavoid TypeInferenceVisitor::Visit(MoveResultInstructionNode* instruction) { 606547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea std::vector<const Type*> operand_types = GetOperandTypes(instruction); 616547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea const Type* operand_type = operand_types.at(0); 626547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea crt_type_.push_back(operand_type); 636547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea} 646547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea 656547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirleavoid TypeInferenceVisitor::Visit(InvokeStaticInstructionNode* instruction) { 666547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea FunctionTypeInfo fti(graph_, instruction, type_cache_); 676547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea const Type* result_type = fti.GetReturnValueType(); 686547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea crt_type_.push_back(result_type); 696547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea} 706547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea 71423fb4d70f2ac36bf9f630146b4150771a8e7e76Dragos Sbirleastd::vector<const Type*> TypeInferenceVisitor::GetOperandTypes( 72423fb4d70f2ac36bf9f630146b4150771a8e7e76Dragos Sbirlea InstructionNode* instruction) const { 736547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea std::vector<InstructionNode*> sources = instruction->GetSSAProducers(); 746547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea std::vector<const Type*> types_to_merge; 756547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea for (std::vector<InstructionNode*>::const_iterator cit = sources.begin(); cit != sources.end(); 766547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea cit++) { 776547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea const Type* source_type = type_data_->FindTypeOf((*cit)->Id()); 786547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea if (source_type != NULL) { 796547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea types_to_merge.push_back(source_type); 806547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea } 816547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea } 826547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea return types_to_merge; 836547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea} 846547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea 856547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirleaconst Type* TypeInferenceVisitor::MergeTypes(std::vector<const Type*>& types) const { 866547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea const Type* type = NULL; 8702e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier if (types.size() > 0) { 886547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea type = *(types.begin()); 8902e25119b15a6f619f17db99f5d05124a5807ff3Mathieu Chartier if (types.size() > 1) { 906547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea for (std::vector<const Type*>::const_iterator cit = types.begin(); 916547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea cit != types.end(); cit++) { 926547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea if (!type->Equals(**cit)) { 936547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea type = MergeTypes(type, *cit); 946547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea } 956547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea } 966547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea } 976547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea } 986547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea return type; 996547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea} 1006547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea 1016547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirleaconst Type* TypeInferenceVisitor::MergeTypes(const Type* t1, const Type* t2) const { 1026547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea DCHECK(t2 != NULL); 1036547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea DCHECK(t1 != NULL); 1046547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea art::ScopedObjectAccess soa(art::Thread::Current()); 1056547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea const Type* result = &(t1->Merge(*t2, type_cache_)); 1066547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea return result; 1076547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea} 1086547fa9749d0e32cc367d64f8cc6b3d65bf43a5dDragos Sbirlea 1096447919b5ee8d34c4767f908c7cd7223c224544cDragos Sbirlea} // namespace sea_ir 110