[llvm-commits] [llvm] r159202 - in /llvm/trunk: lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp test/Transforms/InstCombine/alloca.ll
Duncan Sands
baldrick at free.fr
Tue Jun 26 08:38:09 PDT 2012
Hi David,
>> Replacing zero-sized alloca's with a null pointer is too aggressive, instead
>> merge all zero-sized alloca's into one,
>
> Is that sufficient? At least C++'s new is guaranteed to return a
> unique (for its lifetime), undereferencable, pointer for each
> zero-sized allocation. But I don't know how alloca's correlate to any
> particular other language features that may or may not have similar
> semantics.
I don't know either for C++, but I think it suffices for Ada.
Ciao, Duncan.
>
> - David
>
>> fixing c43204g from the Ada ACATS
>> conformance testsuite. What happened there was that a variable sized object
>> was being allocated on the stack, "alloca i8, i32 %size". It was then being
>> passed to another function, which tested that the address was not null (raising
>> an exception if it was) then manipulated %size bytes in it (load and/or store).
>> The optimizers cleverly managed to deduce that %size was zero (congratulations
>> to them, as it isn't at all obvious), which made the alloca zero size, causing
>> the optimizers to replace it with null, which then caused the check mentioned
>> above to fail, and the exception to be raised, wrongly. Note that no loads
>> and stores were actually being done to the alloca (the loop that does them is
>> executed %size times, i.e. is not executed), only the not-null address check.
>>
>> Modified:
>> llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
>> llvm/trunk/test/Transforms/InstCombine/alloca.ll
>>
>> Modified: llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp?rev=159202&r1=159201&r2=159202&view=diff
>> ==============================================================================
>> --- llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp (original)
>> +++ llvm/trunk/lib/Transforms/InstCombine/InstCombineLoadStoreAlloca.cpp Tue Jun 26 08:39:21 2012
>> @@ -106,7 +106,6 @@
>> if (const ConstantInt *C = dyn_cast<ConstantInt>(AI.getArraySize())) {
>> Type *NewTy =
>> ArrayType::get(AI.getAllocatedType(), C->getZExtValue());
>> - assert(isa<AllocaInst>(AI) && "Unknown type of allocation inst!");
>> AllocaInst *New = Builder->CreateAlloca(NewTy, 0, AI.getName());
>> New->setAlignment(AI.getAlignment());
>>
>> @@ -135,16 +134,49 @@
>> }
>> }
>>
>> - if (TD && isa<AllocaInst>(AI) && AI.getAllocatedType()->isSized()) {
>> - // If alloca'ing a zero byte object, replace the alloca with a null pointer.
>> - // Note that we only do this for alloca's, because malloc should allocate
>> - // and return a unique pointer, even for a zero byte allocation.
>> - if (TD->getTypeAllocSize(AI.getAllocatedType()) == 0)
>> - return ReplaceInstUsesWith(AI, Constant::getNullValue(AI.getType()));
>> -
>> + if (TD && AI.getAllocatedType()->isSized()) {
>> // If the alignment is 0 (unspecified), assign it the preferred alignment.
>> if (AI.getAlignment() == 0)
>> AI.setAlignment(TD->getPrefTypeAlignment(AI.getAllocatedType()));
>> +
>> + // Move all alloca's of zero byte objects to the entry block and merge them
>> + // together. Note that we only do this for alloca's, because malloc should
>> + // allocate and return a unique pointer, even for a zero byte allocation.
>> + if (TD->getTypeAllocSize(AI.getAllocatedType()) == 0) {
>> + // For a zero sized alloca there is no point in doing an array allocation.
>> + // This is helpful if the array size is a complicated expression not used
>> + // elsewhere.
>> + if (AI.isArrayAllocation()) {
>> + AI.setOperand(0, ConstantInt::get(AI.getArraySize()->getType(), 1));
>> + return &AI;
>> + }
>> +
>> + // Get the first instruction in the entry block.
>> + BasicBlock &EntryBlock = AI.getParent()->getParent()->getEntryBlock();
>> + Instruction *FirstInst = EntryBlock.getFirstNonPHIOrDbg();
>> + if (FirstInst != &AI) {
>> + // If the entry block doesn't start with a zero-size alloca then move
>> + // this one to the start of the entry block. There is no problem with
>> + // dominance as the array size was forced to a constant earlier already.
>> + AllocaInst *EntryAI = dyn_cast<AllocaInst>(FirstInst);
>> + if (!EntryAI || !EntryAI->getAllocatedType()->isSized() ||
>> + TD->getTypeAllocSize(EntryAI->getAllocatedType()) != 0) {
>> + AI.moveBefore(FirstInst);
>> + return &AI;
>> + }
>> +
>> + // Replace this zero-sized alloca with the one at the start of the entry
>> + // block after ensuring that the address will be aligned enough for both
>> + // types.
>> + unsigned MaxAlign =
>> + std::max(TD->getPrefTypeAlignment(EntryAI->getAllocatedType()),
>> + TD->getPrefTypeAlignment(AI.getAllocatedType()));
>> + EntryAI->setAlignment(MaxAlign);
>> + if (AI.getType() != EntryAI->getType())
>> + return new BitCastInst(EntryAI, AI.getType());
>> + return ReplaceInstUsesWith(AI, EntryAI);
>> + }
>> + }
>> }
>>
>> // Try to aggressively remove allocas which are only used for GEPs, lifetime
>>
>> Modified: llvm/trunk/test/Transforms/InstCombine/alloca.ll
>> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/test/Transforms/InstCombine/alloca.ll?rev=159202&r1=159201&r2=159202&view=diff
>> ==============================================================================
>> --- llvm/trunk/test/Transforms/InstCombine/alloca.ll (original)
>> +++ llvm/trunk/test/Transforms/InstCombine/alloca.ll Tue Jun 26 08:39:21 2012
>> @@ -5,8 +5,11 @@
>>
>> declare void @use(...)
>>
>> -; Zero byte allocas should be deleted.
>> + at int = global i32 zeroinitializer
>> +
>> +; Zero byte allocas should be merged if they can't be deleted.
>> ; CHECK: @test
>> +; CHECK: alloca
>> ; CHECK-NOT: alloca
>> define void @test() {
>> %X = alloca [0 x i32] ; <[0 x i32]*> [#uses=1]
>> @@ -15,6 +18,9 @@
>> call void (...)* @use( i32* %Y )
>> %Z = alloca { } ; <{ }*> [#uses=1]
>> call void (...)* @use( { }* %Z )
>> + %size = load i32* @int
>> + %A = alloca {{}}, i32 %size
>> + call void (...)* @use( {{}}* %A )
>> ret void
>> }
>>
>>
>>
>> _______________________________________________
>> llvm-commits mailing list
>> llvm-commits at cs.uiuc.edu
>> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list