| /* |
| * Copyright (C) 2012 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. |
| */ |
| |
| #ifndef ART_SRC_GREENLAND_IR_BUILDER_H_ |
| #define ART_SRC_GREENLAND_IR_BUILDER_H_ |
| |
| #include "backend_types.h" |
| #include "intrinsic_helper.h" |
| |
| #include "logging.h" |
| |
| #include <llvm/Support/IRBuilder.h> |
| #include <llvm/Support/NoFolder.h> |
| #include <llvm/Metadata.h> |
| |
| namespace llvm { |
| class Module; |
| } |
| |
| namespace art { |
| namespace greenland { |
| |
| #if defined(ART_USE_QUICK_COMPILER) |
| class InserterWithDexOffset |
| : public llvm::IRBuilderDefaultInserter<true> { |
| public: |
| InserterWithDexOffset() : node_(NULL) {} |
| void InsertHelper(llvm::Instruction *I, const llvm::Twine &Name, |
| llvm::BasicBlock *BB, |
| llvm::BasicBlock::iterator InsertPt) const { |
| llvm::IRBuilderDefaultInserter<true>::InsertHelper(I, Name, BB, InsertPt); |
| if (node_ != NULL) { |
| I->setMetadata("DexOff", node_); |
| } |
| } |
| void SetDexOffset(llvm::MDNode* node) { |
| node_ = node; |
| } |
| private: |
| llvm::MDNode* node_; |
| }; |
| |
| typedef llvm::IRBuilder<true, llvm::NoFolder, InserterWithDexOffset> LLVMIRBuilder; |
| #else |
| typedef llvm::IRBuilder<true> LLVMIRBuilder; |
| #endif |
| |
| class IRBuilder : public LLVMIRBuilder { |
| public: |
| IRBuilder(llvm::LLVMContext& context, llvm::Module& module, |
| IntrinsicHelper& intrinsic_helper); |
| ~IRBuilder() { } |
| |
| public: |
| //-------------------------------------------------------------------------- |
| // Pointer Arithmetic Helper Function |
| //-------------------------------------------------------------------------- |
| llvm::IntegerType* GetPtrEquivIntTy() { |
| return getInt32Ty(); |
| } |
| |
| llvm::ConstantInt* GetPtrEquivInt(int64_t i) { |
| return llvm::ConstantInt::get(GetPtrEquivIntTy(), i); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // Intrinsic Helper Functions |
| //-------------------------------------------------------------------------- |
| llvm::Function* GetIntrinsics(IntrinsicHelper::IntrinsicId instr_id) { |
| return intrinsic_helper_.GetIntrinsicFunction(instr_id); |
| } |
| |
| //-------------------------------------------------------------------------- |
| // Type Helper Functions |
| //-------------------------------------------------------------------------- |
| llvm::Type* GetJType(char shorty_jty, JTypeSpace space) { |
| return GetJType(GetJTypeFromShorty(shorty_jty), space); |
| } |
| |
| llvm::Type* GetJType(JType jty, JTypeSpace space) { |
| switch (space) { |
| case kAccurate: |
| return GetJTypeInAccurateSpace(jty); |
| |
| case kReg: |
| case kField: // Currently field space is equivalent to register space. |
| return GetJTypeInRegSpace(jty); |
| |
| case kArray: |
| return GetJTypeInArraySpace(jty); |
| } |
| |
| LOG(FATAL) << "Unknown type space: " << space; |
| return NULL; |
| } |
| |
| llvm::Type* GetJVoidTy() { |
| return getVoidTy(); |
| } |
| |
| llvm::IntegerType* GetJBooleanTy() { |
| return getInt1Ty(); |
| } |
| |
| llvm::IntegerType* GetJByteTy() { |
| return getInt8Ty(); |
| } |
| |
| llvm::IntegerType* GetJCharTy() { |
| return getInt16Ty(); |
| } |
| |
| llvm::IntegerType* GetJShortTy() { |
| return getInt16Ty(); |
| } |
| |
| llvm::IntegerType* GetJIntTy() { |
| return getInt32Ty(); |
| } |
| |
| llvm::IntegerType* GetJLongTy() { |
| return getInt64Ty(); |
| } |
| |
| llvm::Type* GetJFloatTy() { |
| return getFloatTy(); |
| } |
| |
| llvm::Type* GetJDoubleTy() { |
| return getDoubleTy(); |
| } |
| |
| llvm::PointerType* GetJObjectTy() { |
| return java_object_type_; |
| } |
| |
| llvm::PointerType* GetJMethodTy() { |
| return java_method_type_; |
| } |
| |
| llvm::PointerType* GetJThreadTy() { |
| return java_thread_type_; |
| } |
| |
| //-------------------------------------------------------------------------- |
| // Constant Value Helper Function |
| //-------------------------------------------------------------------------- |
| llvm::ConstantInt* GetJBoolean(bool is_true) { |
| return (is_true) ? getTrue() : getFalse(); |
| } |
| |
| llvm::ConstantInt* GetJByte(int8_t i) { |
| return llvm::ConstantInt::getSigned(GetJByteTy(), i); |
| } |
| |
| llvm::ConstantInt* GetJChar(int16_t i) { |
| return llvm::ConstantInt::getSigned(GetJCharTy(), i); |
| } |
| |
| llvm::ConstantInt* GetJShort(int16_t i) { |
| return llvm::ConstantInt::getSigned(GetJShortTy(), i); |
| } |
| |
| llvm::ConstantInt* GetJInt(int32_t i) { |
| return llvm::ConstantInt::getSigned(GetJIntTy(), i); |
| } |
| |
| llvm::ConstantInt* GetJLong(int64_t i) { |
| return llvm::ConstantInt::getSigned(GetJLongTy(), i); |
| } |
| |
| llvm::Constant* GetJFloat(float f) { |
| return llvm::ConstantFP::get(GetJFloatTy(), f); |
| } |
| |
| llvm::Constant* GetJDouble(double d) { |
| return llvm::ConstantFP::get(GetJDoubleTy(), d); |
| } |
| |
| llvm::ConstantPointerNull* GetJNull() { |
| return llvm::ConstantPointerNull::get(GetJObjectTy()); |
| } |
| |
| llvm::Constant* GetJZero(char shorty_jty) { |
| return GetJZero(GetJTypeFromShorty(shorty_jty)); |
| } |
| |
| llvm::Constant* GetJZero(JType jty) { |
| switch (jty) { |
| case kVoid: |
| LOG(FATAL) << "Zero is not a value of void type"; |
| return NULL; |
| |
| case kBoolean: |
| return GetJBoolean(false); |
| |
| case kByte: |
| return GetJByte(0); |
| |
| case kChar: |
| return GetJChar(0); |
| |
| case kShort: |
| return GetJShort(0); |
| |
| case kInt: |
| return GetJInt(0); |
| |
| case kLong: |
| return GetJLong(0); |
| |
| case kFloat: |
| return GetJFloat(0.0f); |
| |
| case kDouble: |
| return GetJDouble(0.0); |
| |
| case kObject: |
| return GetJNull(); |
| |
| default: |
| LOG(FATAL) << "Unknown java type: " << jty; |
| return NULL; |
| } |
| } |
| |
| private: |
| llvm::Type* GetJTypeInAccurateSpace(JType jty); |
| llvm::Type* GetJTypeInRegSpace(JType jty); |
| llvm::Type* GetJTypeInArraySpace(JType jty); |
| |
| llvm::PointerType* java_object_type_; |
| llvm::PointerType* java_method_type_; |
| llvm::PointerType* java_thread_type_; |
| |
| IntrinsicHelper& intrinsic_helper_; |
| }; |
| |
| } // namespace greenland |
| } // namespace art |
| |
| #endif // ART_SRC_GREENLAND_IR_BUILDER_H_ |