summaryrefslogtreecommitdiffstats
path: root/compiler/sea_ir
diff options
context:
space:
mode:
authorDragos Sbirlea <dragoss@google.com>2013-08-05 18:33:30 -0700
committerDragos Sbirlea <dragoss@google.com>2013-08-07 17:35:18 -0700
commit423fb4d70f2ac36bf9f630146b4150771a8e7e76 (patch)
treebbb7f84bf2b0b7beeb57b17a51cbe84dd7cfd228 /compiler/sea_ir
parenta3519a48b94abfaf6571f5e9bbbe943e0fc314c2 (diff)
downloadart-423fb4d70f2ac36bf9f630146b4150771a8e7e76.zip
art-423fb4d70f2ac36bf9f630146b4150771a8e7e76.tar.gz
art-423fb4d70f2ac36bf9f630146b4150771a8e7e76.tar.bz2
Add tests for SEA IR types infrastructure.
type_data_test.cc: Tests the type store used to record info on the types of results from instructions. type_inferecen_visitor_test.cc: Tests type merging and related operations. Android.gtest.mk: Included new tests. type_inference_visitor.h/.cc: Marked function as const and made public. scoped_hashtable_test.cc: Included full header path in #include. Change-Id: I868461dcaed1e7f75db15958b83a3db7e17f6a64
Diffstat (limited to 'compiler/sea_ir')
-rw-r--r--compiler/sea_ir/types/type_data_test.cc41
-rw-r--r--compiler/sea_ir/types/type_inference_visitor.cc3
-rw-r--r--compiler/sea_ir/types/type_inference_visitor.h5
-rw-r--r--compiler/sea_ir/types/type_inference_visitor_test.cc133
4 files changed, 177 insertions, 5 deletions
diff --git a/compiler/sea_ir/types/type_data_test.cc b/compiler/sea_ir/types/type_data_test.cc
new file mode 100644
index 0000000..a66ebce
--- /dev/null
+++ b/compiler/sea_ir/types/type_data_test.cc
@@ -0,0 +1,41 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common_test.h"
+#include "sea_ir/types/types.h"
+
+namespace sea_ir {
+
+class TypeDataTest : public art::CommonTest {
+};
+
+TEST_F(TypeDataTest, Basics) {
+ TypeData td;
+ art::verifier::RegTypeCache type_cache(false);
+ int first_instruction_id = 1;
+ int second_instruction_id = 3;
+ EXPECT_TRUE(NULL == td.FindTypeOf(first_instruction_id));
+ const Type* int_type = &type_cache.Integer();
+ const Type* byte_type = &type_cache.Byte();
+ td.SetTypeOf(first_instruction_id, int_type);
+ EXPECT_TRUE(int_type == td.FindTypeOf(first_instruction_id));
+ EXPECT_TRUE(NULL == td.FindTypeOf(second_instruction_id));
+ td.SetTypeOf(second_instruction_id, byte_type);
+ EXPECT_TRUE(int_type == td.FindTypeOf(first_instruction_id));
+ EXPECT_TRUE(byte_type == td.FindTypeOf(second_instruction_id));
+}
+
+} // namespace art
diff --git a/compiler/sea_ir/types/type_inference_visitor.cc b/compiler/sea_ir/types/type_inference_visitor.cc
index 30537bd..3da2fc1 100644
--- a/compiler/sea_ir/types/type_inference_visitor.cc
+++ b/compiler/sea_ir/types/type_inference_visitor.cc
@@ -62,7 +62,8 @@ void TypeInferenceVisitor::Visit(InvokeStaticInstructionNode* instruction) {
crt_type_.push_back(result_type);
}
-std::vector<const Type*> TypeInferenceVisitor::GetOperandTypes(InstructionNode* instruction) {
+std::vector<const Type*> TypeInferenceVisitor::GetOperandTypes(
+ InstructionNode* instruction) const {
std::vector<InstructionNode*> sources = instruction->GetSSAProducers();
std::vector<const Type*> types_to_merge;
for (std::vector<InstructionNode*>::const_iterator cit = sources.begin(); cit != sources.end();
diff --git a/compiler/sea_ir/types/type_inference_visitor.h b/compiler/sea_ir/types/type_inference_visitor.h
index be1ad43..200b9f0 100644
--- a/compiler/sea_ir/types/type_inference_visitor.h
+++ b/compiler/sea_ir/types/type_inference_visitor.h
@@ -58,7 +58,7 @@ class TypeInferenceVisitor: public IRVisitor {
const Type* MergeTypes(std::vector<const Type*>& types) const;
const Type* MergeTypes(const Type* t1, const Type* t2) const;
-
+ std::vector<const Type*> GetOperandTypes(InstructionNode* instruction) const;
const Type* GetType() {
// TODO: Currently multiple defined types are not supported.
if (crt_type_.size()>0) {
@@ -74,9 +74,6 @@ class TypeInferenceVisitor: public IRVisitor {
TypeData* type_data_;
art::verifier::RegTypeCache* type_cache_;
std::vector<const Type*> crt_type_; // Stored temporarily between two calls to Visit.
-
- private:
- std::vector<const Type*> GetOperandTypes(InstructionNode* instruction);
};
} // namespace sea_ir
diff --git a/compiler/sea_ir/types/type_inference_visitor_test.cc b/compiler/sea_ir/types/type_inference_visitor_test.cc
new file mode 100644
index 0000000..8a249eb
--- /dev/null
+++ b/compiler/sea_ir/types/type_inference_visitor_test.cc
@@ -0,0 +1,133 @@
+/*
+ * Copyright (C) 2013 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "common_test.h"
+#include "sea_ir/types/type_inference_visitor.h"
+#include "sea_ir/ir/sea.h"
+
+namespace sea_ir {
+
+class TestInstructionNode:public InstructionNode {
+ public:
+ explicit TestInstructionNode(std::vector<InstructionNode*> prods): InstructionNode(NULL),
+ producers_(prods) { }
+ std::vector<InstructionNode*> GetSSAProducers() {
+ return producers_;
+ }
+ protected:
+ std::vector<InstructionNode*> producers_;
+};
+
+class TypeInferenceVisitorTest : public art::CommonTest {
+};
+
+TEST_F(TypeInferenceVisitorTest, MergeIntWithByte) {
+ TypeData td;
+ art::verifier::RegTypeCache type_cache(false);
+ TypeInferenceVisitor tiv(NULL, &td, &type_cache);
+ const Type* int_type = &type_cache.Integer();
+ const Type* byte_type = &type_cache.Byte();
+ const Type* ib_type = tiv.MergeTypes(int_type, byte_type);
+ const Type* bi_type = tiv.MergeTypes(byte_type, int_type);
+ EXPECT_TRUE(ib_type == int_type);
+ EXPECT_TRUE(bi_type == int_type);
+}
+
+TEST_F(TypeInferenceVisitorTest, MergeIntWithShort) {
+ TypeData td;
+ art::verifier::RegTypeCache type_cache(false);
+ TypeInferenceVisitor tiv(NULL, &td, &type_cache);
+ const Type* int_type = &type_cache.Integer();
+ const Type* short_type = &type_cache.Short();
+ const Type* is_type = tiv.MergeTypes(int_type, short_type);
+ const Type* si_type = tiv.MergeTypes(short_type, int_type);
+ EXPECT_TRUE(is_type == int_type);
+ EXPECT_TRUE(si_type == int_type);
+}
+
+TEST_F(TypeInferenceVisitorTest, MergeMultipleInts) {
+ int N = 10; // Number of types to merge.
+ TypeData td;
+ art::verifier::RegTypeCache type_cache(false);
+ TypeInferenceVisitor tiv(NULL, &td, &type_cache);
+ std::vector<const Type*> types;
+ for (int i = 0; i < N; i++) {
+ const Type* new_type = &type_cache.Integer();
+ types.push_back(new_type);
+ }
+ const Type* merged_type = tiv.MergeTypes(types);
+ EXPECT_TRUE(merged_type == &type_cache.Integer());
+}
+
+TEST_F(TypeInferenceVisitorTest, MergeMultipleShorts) {
+ int N = 10; // Number of types to merge.
+ TypeData td;
+ art::verifier::RegTypeCache type_cache(false);
+ TypeInferenceVisitor tiv(NULL, &td, &type_cache);
+ std::vector<const Type*> types;
+ for (int i = 0; i < N; i++) {
+ const Type* new_type = &type_cache.Short();
+ types.push_back(new_type);
+ }
+ const Type* merged_type = tiv.MergeTypes(types);
+ EXPECT_TRUE(merged_type == &type_cache.Short());
+}
+
+TEST_F(TypeInferenceVisitorTest, MergeMultipleIntsWithShorts) {
+ int N = 10; // Number of types to merge.
+ TypeData td;
+ art::verifier::RegTypeCache type_cache(false);
+ TypeInferenceVisitor tiv(NULL, &td, &type_cache);
+ std::vector<const Type*> types;
+ for (int i = 0; i < N; i++) {
+ const Type* short_type = &type_cache.Short();
+ const Type* int_type = &type_cache.Integer();
+ types.push_back(short_type);
+ types.push_back(int_type);
+ }
+ const Type* merged_type = tiv.MergeTypes(types);
+ EXPECT_TRUE(merged_type == &type_cache.Integer());
+}
+
+TEST_F(TypeInferenceVisitorTest, GetOperandTypes) {
+ int N = 10; // Number of types to merge.
+ TypeData td;
+ art::verifier::RegTypeCache type_cache(false);
+ TypeInferenceVisitor tiv(NULL, &td, &type_cache);
+ std::vector<const Type*> types;
+ std::vector<InstructionNode*> preds;
+ for (int i = 0; i < N; i++) {
+ const Type* short_type = &type_cache.Short();
+ const Type* int_type = &type_cache.Integer();
+ TestInstructionNode* short_inst =
+ new TestInstructionNode(std::vector<InstructionNode*>());
+ TestInstructionNode* int_inst =
+ new TestInstructionNode(std::vector<InstructionNode*>());
+ preds.push_back(short_inst);
+ preds.push_back(int_inst);
+ td.SetTypeOf(short_inst->Id(), short_type);
+ td.SetTypeOf(int_inst->Id(), int_type);
+ types.push_back(short_type);
+ types.push_back(int_type);
+ }
+ TestInstructionNode* inst_to_test = new TestInstructionNode(preds);
+ std::vector<const Type*> result = tiv.GetOperandTypes(inst_to_test);
+ EXPECT_TRUE(result.size() == types.size());
+ EXPECT_TRUE(true == std::equal(types.begin(), types.begin() + 2, result.begin()));
+}
+
+
+} // namespace art