From ef854af5bd231ae0c059eb4f07d13352d2a50a9d Mon Sep 17 00:00:00 2001 From: Duncan Sands Date: Thu, 21 May 2009 15:52:21 +0000 Subject: [PATCH] Add a getAlignOf helper for getting the ABI alignment of a type as a target independent constant expression. I confess that I didn't check that this method works as intended (though I did test the equivalent hand-written IR a little). But what could possibly go wrong! git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@72213 91177308-0d34-0410-b5e6-96231b3b80d8 --- bindings/ocaml/llvm/llvm.mli | 8 +++++++- include/llvm/Constants.h | 6 ++++++ lib/VMCore/Constants.cpp | 11 +++++++++++ lib/VMCore/Core.cpp | 4 ++++ 4 files changed, 28 insertions(+), 1 deletion(-) diff --git a/bindings/ocaml/llvm/llvm.mli b/bindings/ocaml/llvm/llvm.mli index 421c20cba96..f7ca58ef926 100644 --- a/bindings/ocaml/llvm/llvm.mli +++ b/bindings/ocaml/llvm/llvm.mli @@ -514,9 +514,15 @@ external const_vector : llvalue array -> llvalue = "llvm_const_vector" (** {7 Constant expressions} *) +(** [align_of ty] returns the alignof constant for the type [ty]. This is + equivalent to [const_ptrtoint (const_gep (const_null (pointer_type {i8,ty})) + (const_int i32_type 0) (const_int i32_type 1)) i32_type], but considerably + more readable. See the method [llvm::ConstantExpr::getAlignOf]. *) +external align_of : lltype -> llvalue = "LLVMAlignOf" + (** [size_of ty] returns the sizeof constant for the type [ty]. This is equivalent to [const_ptrtoint (const_gep (const_null (pointer_type ty)) - (const_int i64_type 1)) i64_type], but considerably more readable. + (const_int i32_type 1)) i64_type], but considerably more readable. See the method [llvm::ConstantExpr::getSizeOf]. *) external size_of : lltype -> llvalue = "LLVMSizeOf" diff --git a/include/llvm/Constants.h b/include/llvm/Constants.h index 0b908e90025..d72ca0b7433 100644 --- a/include/llvm/Constants.h +++ b/include/llvm/Constants.h @@ -680,6 +680,12 @@ public: return getSelectTy(V1->getType(), C, V1, V2); } + /// getAlignOf constant expr - computes the alignment of a type in a target + /// independent way (Note: the return type is an i32; Note: assumes that i8 + /// is byte aligned). + /// + static Constant *getAlignOf(const Type *Ty); + /// getSizeOf constant expr - computes the size of a type in a target /// independent way (Note: the return type is an i64). /// diff --git a/lib/VMCore/Constants.cpp b/lib/VMCore/Constants.cpp index b38474d28a4..d3f9b7f45b7 100644 --- a/lib/VMCore/Constants.cpp +++ b/lib/VMCore/Constants.cpp @@ -2082,6 +2082,17 @@ Constant *ConstantExpr::getBitCast(Constant *C, const Type *DstTy) { return getFoldedCast(Instruction::BitCast, C, DstTy); } +Constant *ConstantExpr::getAlignOf(const Type *Ty) { + // alignof is implemented as: (i64) gep ({i8,Ty}*)null, 0, 1 + const Type *AligningTy = StructType::get(Type::Int8Ty, Ty, NULL); + Constant *NullPtr = getNullValue(AligningTy->getPointerTo()); + Constant *Zero = ConstantInt::get(Type::Int32Ty, 0); + Constant *One = ConstantInt::get(Type::Int32Ty, 1); + Constant *Indices[2] = { Zero, One }; + Constant *GEP = getGetElementPtr(NullPtr, Indices, 2); + return getCast(Instruction::PtrToInt, GEP, Type::Int32Ty); +} + Constant *ConstantExpr::getSizeOf(const Type *Ty) { // sizeof is implemented as: (i64) gep (Ty*)null, 1 Constant *GEPIdx = ConstantInt::get(Type::Int32Ty, 1); diff --git a/lib/VMCore/Core.cpp b/lib/VMCore/Core.cpp index 1fa83ebd1c0..f85dbe76119 100644 --- a/lib/VMCore/Core.cpp +++ b/lib/VMCore/Core.cpp @@ -356,6 +356,10 @@ LLVMValueRef LLVMConstVector(LLVMValueRef *ScalarConstantVals, unsigned Size) { /*--.. Constant expressions ................................................--*/ +LLVMValueRef LLVMAlignOf(LLVMTypeRef Ty) { + return wrap(ConstantExpr::getAlignOf(unwrap(Ty))); +} + LLVMValueRef LLVMSizeOf(LLVMTypeRef Ty) { return wrap(ConstantExpr::getSizeOf(unwrap(Ty))); } -- 2.34.1