1 /*
2  * Copyright (C) 2012 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 #include "ir_builder.h"
18 
19 #include "base/stringprintf.h"
20 
21 #include <llvm/IR/Module.h>
22 
23 namespace art {
24 namespace llvm {
25 
26 
27 //----------------------------------------------------------------------------
28 // General
29 //----------------------------------------------------------------------------
30 
IRBuilder(::llvm::LLVMContext & context,::llvm::Module & module,IntrinsicHelper & intrinsic_helper)31 IRBuilder::IRBuilder(::llvm::LLVMContext& context, ::llvm::Module& module,
32                      IntrinsicHelper& intrinsic_helper)
33     : LLVMIRBuilder(context), module_(&module), mdb_(context), java_object_type_(NULL),
34       java_method_type_(NULL), java_thread_type_(NULL), intrinsic_helper_(intrinsic_helper) {
35   // Get java object type from module
36   ::llvm::Type* jobject_struct_type = module.getTypeByName("JavaObject");
37   CHECK(jobject_struct_type != NULL);
38   java_object_type_ = jobject_struct_type->getPointerTo();
39 
40   // If type of Method is not explicitly defined in the module, use JavaObject*
41   ::llvm::Type* type = module.getTypeByName("Method");
42   if (type != NULL) {
43     java_method_type_ = type->getPointerTo();
44   } else {
45     java_method_type_ = java_object_type_;
46   }
47 
48   // If type of Thread is not explicitly defined in the module, use JavaObject*
49   type = module.getTypeByName("Thread");
50   if (type != NULL) {
51     java_thread_type_ = type->getPointerTo();
52   } else {
53     java_thread_type_ = java_object_type_;
54   }
55 
56   // Create JEnv* type
57   ::llvm::Type* jenv_struct_type = ::llvm::StructType::create(context, "JEnv");
58   jenv_type_ = jenv_struct_type->getPointerTo();
59 
60   // Get Art shadow frame struct type from module
61   art_frame_type_ = module.getTypeByName("ShadowFrame");
62   CHECK(art_frame_type_ != NULL);
63 
64   runtime_support_ = NULL;
65 }
66 
67 
68 //----------------------------------------------------------------------------
69 // Type Helper Function
70 //----------------------------------------------------------------------------
71 
getJType(JType jty)72 ::llvm::Type* IRBuilder::getJType(JType jty) {
73   switch (jty) {
74   case kVoid:
75     return getJVoidTy();
76 
77   case kBoolean:
78     return getJBooleanTy();
79 
80   case kByte:
81     return getJByteTy();
82 
83   case kChar:
84     return getJCharTy();
85 
86   case kShort:
87     return getJShortTy();
88 
89   case kInt:
90     return getJIntTy();
91 
92   case kLong:
93     return getJLongTy();
94 
95   case kFloat:
96     return getJFloatTy();
97 
98   case kDouble:
99     return getJDoubleTy();
100 
101   case kObject:
102     return getJObjectTy();
103 
104   default:
105     LOG(FATAL) << "Unknown java type: " << jty;
106     return NULL;
107   }
108 }
109 
getShadowFrameTy(uint32_t vreg_size)110 ::llvm::StructType* IRBuilder::getShadowFrameTy(uint32_t vreg_size) {
111   std::string name(StringPrintf("ShadowFrame%u", vreg_size));
112 
113   // Try to find the existing struct type definition
114   if (::llvm::Type* type = module_->getTypeByName(name)) {
115     CHECK(::llvm::isa< ::llvm::StructType>(type));
116     return static_cast< ::llvm::StructType*>(type);
117   }
118 
119   // Create new struct type definition
120   ::llvm::Type* elem_types[] = {
121     art_frame_type_,
122     ::llvm::ArrayType::get(getInt32Ty(), vreg_size),
123   };
124 
125   return ::llvm::StructType::create(elem_types, name);
126 }
127 
128 
129 }  // namespace llvm
130 }  // namespace art
131