diff options
-rw-r--r-- | lib/Transforms/NaCl/FlattenGlobals.cpp | 25 | ||||
-rw-r--r-- | test/Transforms/NaCl/flatten-globals.ll | 24 |
2 files changed, 25 insertions, 24 deletions
diff --git a/lib/Transforms/NaCl/FlattenGlobals.cpp b/lib/Transforms/NaCl/FlattenGlobals.cpp index 77ce2b36b4..9d33e30465 100644 --- a/lib/Transforms/NaCl/FlattenGlobals.cpp +++ b/lib/Transforms/NaCl/FlattenGlobals.cpp @@ -24,12 +24,13 @@ // 2) A reference to a GlobalValue (a function or global variable) // with an optional 32-bit byte offset added to it (the addend): // -// i8* bitcast (TYPE* @GLOBAL to i8*) -// getelementptr (i8* bitcast (TYPE* @GLOBAL to i8*), i32 0, i32 ADDEND) +// ptrtoint (TYPE* @GLOBAL to i32) +// add (i32 ptrtoint (TYPE* @GLOBAL to i32), i32 ADDEND) // -// Note that if @GLOBAL is an i8 array, LLVM will write the latter as: -// -// getelementptr ([SIZE x i8]* @GLOBAL, i32 0, i32 ADDEND) +// We use ptrtoint+add rather than bitcast+getelementptr because +// the constructor for getelementptr ConstantExprs performs +// constant folding which introduces more complex getelementptrs, +// and it is hard to check that they follow a normal form. // // For completeness, the pass also allows a BlockAddress as well as // a GlobalValue here, although BlockAddresses are currently not @@ -64,7 +65,7 @@ namespace { // has been flattened and may be converted into the normal form. class FlattenedConstant { LLVMContext *Context; - Type *I8Ptr; + IntegerType *IntPtrType; unsigned PtrSize; // A flattened global variable initializer is represented as: @@ -91,7 +92,7 @@ namespace { public: FlattenedConstant(DataLayout *DL, Constant *Value): Context(&Value->getContext()) { - I8Ptr = Type::getInt8Ty(*Context)->getPointerTo(); + IntPtrType = DL->getIntPtrType(*Context); PtrSize = DL->getPointerSize(); BufSize = DL->getTypeAllocSize(Value->getType()); Buf = new uint8_t[BufSize]; @@ -193,7 +194,7 @@ void FlattenedConstant::putAtDest(DataLayout *DL, Constant *Val, uint64_t Offset; ExpandConstant(DL, Val, &GV, &Offset); if (GV) { - Constant *NewVal = ConstantExpr::getBitCast(GV, I8Ptr); + Constant *NewVal = ConstantExpr::getPtrToInt(GV, IntPtrType); if (Offset) { // For simplicity, require addends to be 32-bit. if ((int64_t) Offset != (int32_t) (uint32_t) Offset) { @@ -201,8 +202,8 @@ void FlattenedConstant::putAtDest(DataLayout *DL, Constant *Val, report_fatal_error( "FlattenGlobals: Offset does not fit into 32 bits"); } - NewVal = ConstantExpr::getGetElementPtr( - NewVal, ConstantInt::get(*Context, APInt(32, Offset))); + NewVal = ConstantExpr::getAdd( + NewVal, ConstantInt::get(IntPtrType, Offset, /* isSigned= */ true)); } Reloc NewRel = { Dest - Buf, NewVal }; Relocs.push_back(NewRel); @@ -261,8 +262,8 @@ bool FlattenGlobals::runOnModule(Module &M) { Type *NewType; if (Global->hasInitializer()) { if (Global->getInitializer()->isNullValue()) { - // As optimization, for large BSS variables, avoid allocating - // a buffer that would only be filled with zeroes. + // As an optimization, for large BSS variables, avoid + // allocating a buffer that would only be filled with zeroes. NewType = ArrayType::get(I8, Size); NewInit = ConstantAggregateZero::get(NewType); } else { diff --git a/test/Transforms/NaCl/flatten-globals.ll b/test/Transforms/NaCl/flatten-globals.ll index 938f11fec7..565eb4edc6 100644 --- a/test/Transforms/NaCl/flatten-globals.ll +++ b/test/Transforms/NaCl/flatten-globals.ll @@ -118,36 +118,36 @@ target datalayout = "p:32:32:32" %ptrs1 = type { i32*, i8*, i32 } @ptrs1 = global %ptrs1 { i32* @var1, i8* null, i32 259 } -; CHECK: @ptrs1 = global <{ i8*, [8 x i8] }> <{ i8* getelementptr inbounds ([4 x i8]* @var1, i32 0, i32 0), [8 x i8] c"\00\00\00\00\03\01\00\00" }> +; CHECK: @ptrs1 = global <{ i32, [8 x i8] }> <{ i32 ptrtoint ([4 x i8]* @var1 to i32), [8 x i8] c"\00\00\00\00\03\01\00\00" }> %ptrs2 = type { i32, i32*, i8* } @ptrs2 = global %ptrs2 { i32 259, i32* @var1, i8* @var2 } -; CHECK: @ptrs2 = global <{ [4 x i8], i8*, i8* }> <{ [4 x i8] c"\03\01\00\00", i8* getelementptr inbounds ([4 x i8]* @var1, i32 0, i32 0), i8* getelementptr inbounds ([1 x i8]* @var2, i32 0, i32 0) }> +; CHECK: @ptrs2 = global <{ [4 x i8], i32, i32 }> <{ [4 x i8] c"\03\01\00\00", i32 ptrtoint ([4 x i8]* @var1 to i32), i32 ptrtoint ([1 x i8]* @var2 to i32) }> %ptrs3 = type { i32*, [3 x i8], i8* } @ptrs3 = global %ptrs3 { i32* @var1, [3 x i8] c"foo", i8* @var2 } -; CHECK: @ptrs3 = global <{ i8*, [4 x i8], i8* }> <{ i8* getelementptr inbounds ([4 x i8]* @var1, i32 0, i32 0), [4 x i8] c"foo\00", i8* getelementptr inbounds ([1 x i8]* @var2, i32 0, i32 0) }> +; CHECK: @ptrs3 = global <{ i32, [4 x i8], i32 }> <{ i32 ptrtoint ([4 x i8]* @var1 to i32), [4 x i8] c"foo\00", i32 ptrtoint ([1 x i8]* @var2 to i32) }> @ptr = global i32* @var1 -; CHECK: @ptr = global i8* getelementptr inbounds ([4 x i8]* @var1, i32 0, i32 0) +; CHECK: @ptr = global i32 ptrtoint ([4 x i8]* @var1 to i32) @func_ptr = global i32* ()* @get_address -; CHECK: @func_ptr = global i8* bitcast (i32* ()* @get_address to i8*) +; CHECK: @func_ptr = global i32 ptrtoint (i32* ()* @get_address to i32) @block_addr = global i8* blockaddress(@func_with_block, %label) -; CHECK: @block_addr = global i8* blockaddress(@func_with_block, %label) +; CHECK: @block_addr = global i32 ptrtoint (i8* blockaddress(@func_with_block, %label) to i32) @vector_reloc = global <2 x i32*> <i32* @var1, i32* @var1> -; CHECK: @vector_reloc = global <{ i8*, i8* }> <{ i8* getelementptr inbounds ([4 x i8]* @var1, i32 0, i32 0), i8* getelementptr inbounds ([4 x i8]* @var1, i32 0, i32 0) }> +; CHECK: global <{ i32, i32 }> <{ i32 ptrtoint ([4 x i8]* @var1 to i32), i32 ptrtoint ([4 x i8]* @var1 to i32) }> ; Global references with addends @reloc_addend = global i32* getelementptr (%ptrs1* @ptrs1, i32 0, i32 2) -; CHECK: @reloc_addend = global i8* getelementptr (i8* bitcast (<{ i8*, [8 x i8] }>* @ptrs1 to i8*), i32 8) +; CHECK: @reloc_addend = global i32 add (i32 ptrtoint (<{ i32, [8 x i8] }>* @ptrs1 to i32), i32 8) @negative_addend = global %ptrs1* getelementptr (%ptrs1* @ptrs1, i32 -1) -; CHECK: @negative_addend = global i8* getelementptr (i8* bitcast (<{ i8*, [8 x i8] }>* @ptrs1 to i8*), i32 -12) +; CHECK: @negative_addend = global i32 add (i32 ptrtoint (<{ i32, [8 x i8] }>* @ptrs1 to i32), i32 -12) @const_ptr = global i32* getelementptr (%ptrs1* null, i32 0, i32 2) ; CHECK: @const_ptr = global [4 x i8] c"\08\00\00\00" @@ -158,7 +158,7 @@ target datalayout = "p:32:32:32" ; Clang allows "(uintptr_t) &var" as a global initializer, so we ; handle this case. @ptr_to_int = global i32 ptrtoint (i8* @var2 to i32) -; CHECK: @ptr_to_int = global i8* getelementptr inbounds ([1 x i8]* @var2, i32 0, i32 0) +; CHECK: @ptr_to_int = global i32 ptrtoint ([1 x i8]* @var2 to i32) ; This is handled via Constant folding. The getelementptr is ; converted to an undef when it is created, so the pass does not see a @@ -170,13 +170,13 @@ target datalayout = "p:32:32:32" ; the pass handles it anyway. @func_addend = global i8* getelementptr ( i8* bitcast (void ()* @func_with_block to i8*), i32 123) -; CHECK: @func_addend = global i8* getelementptr (i8* bitcast (void ()* @func_with_block to i8*), i32 123) +; CHECK: @func_addend = global i32 add (i32 ptrtoint (void ()* @func_with_block to i32), i32 123) ; Similarly, adding an offset to a label address isn't useful, but ; check it anyway. @block_addend = global i8* getelementptr ( i8* blockaddress(@func_with_block, %label), i32 100) -; CHECK: @block_addend = global i8* getelementptr (i8* blockaddress(@func_with_block, %label), i32 100) +; CHECK: @block_addend = global i32 add (i32 ptrtoint (i8* blockaddress(@func_with_block, %label) to i32), i32 100) ; Special cases |