blob: 30537bdca981f9c83fa9014979625f8ed4d144d3 [file] [log] [blame]
Dragos Sbirlea64479192013-08-01 15:38:43 -07001/*
2 * Copyright (C) 2013 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
Dragos Sbirlea6547fa92013-08-05 18:33:30 -070017#include "scoped_thread_state_change.h"
Dragos Sbirlea64479192013-08-01 15:38:43 -070018#include "sea_ir/types/type_inference_visitor.h"
19#include "sea_ir/types/type_inference.h"
Dragos Sbirleabfaf44f2013-08-06 15:41:44 -070020#include "sea_ir/ir/sea.h"
Dragos Sbirlea64479192013-08-01 15:38:43 -070021
22namespace sea_ir {
23
24void TypeInferenceVisitor::Visit(SignatureNode* parameter) {
Dragos Sbirlea64479192013-08-01 15:38:43 -070025 FunctionTypeInfo fti(graph_, type_cache_);
26 std::vector<const Type*> arguments = fti.GetDeclaredArgumentTypes();
Dragos Sbirlea64479192013-08-01 15:38:43 -070027 DCHECK_LT(parameter->GetPositionInSignature(), arguments.size())
28 << "Signature node position not present in signature.";
29 crt_type_.push_back(arguments.at(parameter->GetPositionInSignature()));
30}
31
Dragos Sbirlea6547fa92013-08-05 18:33:30 -070032void TypeInferenceVisitor::Visit(UnnamedConstInstructionNode* instruction) {
33 crt_type_.push_back(&type_cache_->Integer());
34}
35
36void TypeInferenceVisitor::Visit(PhiInstructionNode* instruction) {
37 std::vector<const Type*> types_to_merge = GetOperandTypes(instruction);
38 const Type* result_type = MergeTypes(types_to_merge);
39 crt_type_.push_back(result_type);
40}
41
42void TypeInferenceVisitor::Visit(AddIntInstructionNode* instruction) {
43 std::vector<const Type*> operand_types = GetOperandTypes(instruction);
44 for (std::vector<const Type*>::const_iterator cit = operand_types.begin();
45 cit != operand_types.end(); cit++) {
46 if (*cit != NULL) {
47 DCHECK((*cit)->IsInteger());
48 }
49 }
50 crt_type_.push_back(&type_cache_->Integer());
51}
52
53void TypeInferenceVisitor::Visit(MoveResultInstructionNode* instruction) {
54 std::vector<const Type*> operand_types = GetOperandTypes(instruction);
55 const Type* operand_type = operand_types.at(0);
56 crt_type_.push_back(operand_type);
57}
58
59void TypeInferenceVisitor::Visit(InvokeStaticInstructionNode* instruction) {
60 FunctionTypeInfo fti(graph_, instruction, type_cache_);
61 const Type* result_type = fti.GetReturnValueType();
62 crt_type_.push_back(result_type);
63}
64
65std::vector<const Type*> TypeInferenceVisitor::GetOperandTypes(InstructionNode* instruction) {
66 std::vector<InstructionNode*> sources = instruction->GetSSAProducers();
67 std::vector<const Type*> types_to_merge;
68 for (std::vector<InstructionNode*>::const_iterator cit = sources.begin(); cit != sources.end();
69 cit++) {
70 const Type* source_type = type_data_->FindTypeOf((*cit)->Id());
71 if (source_type != NULL) {
72 types_to_merge.push_back(source_type);
73 }
74 }
75 return types_to_merge;
76}
77
78const Type* TypeInferenceVisitor::MergeTypes(std::vector<const Type*>& types) const {
79 const Type* type = NULL;
80 if (types.size()>0) {
81 type = *(types.begin());
82 if (types.size()>1) {
83 for (std::vector<const Type*>::const_iterator cit = types.begin();
84 cit != types.end(); cit++) {
85 if (!type->Equals(**cit)) {
86 type = MergeTypes(type, *cit);
87 }
88 }
89 }
90 }
91 return type;
92}
93
94const Type* TypeInferenceVisitor::MergeTypes(const Type* t1, const Type* t2) const {
95 DCHECK(t2 != NULL);
96 DCHECK(t1 != NULL);
97 art::ScopedObjectAccess soa(art::Thread::Current());
98 const Type* result = &(t1->Merge(*t2, type_cache_));
99 return result;
100}
101
Dragos Sbirlea64479192013-08-01 15:38:43 -0700102} // namespace sea_ir