diff options
| author | David Majnemer <david.majnemer@gmail.com> | 2016-04-29 08:07:22 +0000 |
|---|---|---|
| committer | David Majnemer <david.majnemer@gmail.com> | 2016-04-29 08:07:22 +0000 |
| commit | fadc6db03679dc7aeeac17a0ca184bf9d93659c7 (patch) | |
| tree | 5c6d1b3234ef8a83d939a84d2b8fcbaae078912c /llvm | |
| parent | 231a68cc22aa7b9acb567008813ea2f8352753da (diff) | |
| download | bcm5719-llvm-fadc6db03679dc7aeeac17a0ca184bf9d93659c7.tar.gz bcm5719-llvm-fadc6db03679dc7aeeac17a0ca184bf9d93659c7.zip | |
[GlobalOpt] Propagate operand bundles
We neglected to transfer operand bundles for some transforms. These
were found via inspection, I'll try to come up with some test cases.
llvm-svn: 268011
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/IR/Instructions.h | 24 | ||||
| -rw-r--r-- | llvm/lib/IR/Instructions.cpp | 58 | ||||
| -rw-r--r-- | llvm/lib/Transforms/IPO/GlobalOpt.cpp | 15 |
3 files changed, 78 insertions, 19 deletions
diff --git a/llvm/include/llvm/IR/Instructions.h b/llvm/include/llvm/IR/Instructions.h index 8ad86906478..63fca499c29 100644 --- a/llvm/include/llvm/IR/Instructions.h +++ b/llvm/include/llvm/IR/Instructions.h @@ -1481,9 +1481,29 @@ public: Value *AllocSize, Value *ArraySize = nullptr, Function* MallocF = nullptr, const Twine &Name = ""); + static Instruction *CreateMalloc(Instruction *InsertBefore, + Type *IntPtrTy, Type *AllocTy, + Value *AllocSize, Value *ArraySize = nullptr, + ArrayRef<OperandBundleDef> Bundles = None, + Function* MallocF = nullptr, + const Twine &Name = ""); + static Instruction *CreateMalloc(BasicBlock *InsertAtEnd, + Type *IntPtrTy, Type *AllocTy, + Value *AllocSize, Value *ArraySize = nullptr, + ArrayRef<OperandBundleDef> Bundles = None, + Function* MallocF = nullptr, + const Twine &Name = ""); /// CreateFree - Generate the IR for a call to the builtin free function. - static Instruction* CreateFree(Value* Source, Instruction *InsertBefore); - static Instruction* CreateFree(Value* Source, BasicBlock *InsertAtEnd); + static Instruction *CreateFree(Value *Source, + Instruction *InsertBefore); + static Instruction *CreateFree(Value *Source, + BasicBlock *InsertAtEnd); + static Instruction *CreateFree(Value *Source, + ArrayRef<OperandBundleDef> Bundles, + Instruction *InsertBefore); + static Instruction *CreateFree(Value *Source, + ArrayRef<OperandBundleDef> Bundles, + BasicBlock *InsertAtEnd); ~CallInst() override; diff --git a/llvm/lib/IR/Instructions.cpp b/llvm/lib/IR/Instructions.cpp index 5cd52f7721c..507ddc6d93d 100644 --- a/llvm/lib/IR/Instructions.cpp +++ b/llvm/lib/IR/Instructions.cpp @@ -408,9 +408,10 @@ static bool IsConstantOne(Value *val) { static Instruction *createMalloc(Instruction *InsertBefore, BasicBlock *InsertAtEnd, Type *IntPtrTy, - Type *AllocTy, Value *AllocSize, - Value *ArraySize, Function *MallocF, - const Twine &Name) { + Type *AllocTy, Value *AllocSize, + Value *ArraySize, + ArrayRef<OperandBundleDef> OpB, + Function *MallocF, const Twine &Name) { assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) && "createMalloc needs either InsertBefore or InsertAtEnd"); @@ -461,13 +462,14 @@ static Instruction *createMalloc(Instruction *InsertBefore, CallInst *MCall = nullptr; Instruction *Result = nullptr; if (InsertBefore) { - MCall = CallInst::Create(MallocFunc, AllocSize, "malloccall", InsertBefore); + MCall = CallInst::Create(MallocFunc, AllocSize, OpB, "malloccall", + InsertBefore); Result = MCall; if (Result->getType() != AllocPtrType) // Create a cast instruction to convert to the right type... Result = new BitCastInst(MCall, AllocPtrType, Name, InsertBefore); } else { - MCall = CallInst::Create(MallocFunc, AllocSize, "malloccall"); + MCall = CallInst::Create(MallocFunc, AllocSize, OpB, "malloccall"); Result = MCall; if (Result->getType() != AllocPtrType) { InsertAtEnd->getInstList().push_back(MCall); @@ -497,9 +499,19 @@ Instruction *CallInst::CreateMalloc(Instruction *InsertBefore, Function *MallocF, const Twine &Name) { return createMalloc(InsertBefore, nullptr, IntPtrTy, AllocTy, AllocSize, - ArraySize, MallocF, Name); + ArraySize, None, MallocF, Name); +} +Instruction *CallInst::CreateMalloc(Instruction *InsertBefore, + Type *IntPtrTy, Type *AllocTy, + Value *AllocSize, Value *ArraySize, + ArrayRef<OperandBundleDef> OpB, + Function *MallocF, + const Twine &Name) { + return createMalloc(InsertBefore, nullptr, IntPtrTy, AllocTy, AllocSize, + ArraySize, OpB, MallocF, Name); } + /// CreateMalloc - Generate the IR for a call to malloc: /// 1. Compute the malloc call's argument as the specified type's size, /// possibly multiplied by the array size if the array size is not @@ -513,10 +525,20 @@ Instruction *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, Value *AllocSize, Value *ArraySize, Function *MallocF, const Twine &Name) { return createMalloc(nullptr, InsertAtEnd, IntPtrTy, AllocTy, AllocSize, - ArraySize, MallocF, Name); + ArraySize, None, MallocF, Name); +} +Instruction *CallInst::CreateMalloc(BasicBlock *InsertAtEnd, + Type *IntPtrTy, Type *AllocTy, + Value *AllocSize, Value *ArraySize, + ArrayRef<OperandBundleDef> OpB, + Function *MallocF, const Twine &Name) { + return createMalloc(nullptr, InsertAtEnd, IntPtrTy, AllocTy, AllocSize, + ArraySize, OpB, MallocF, Name); } -static Instruction *createFree(Value *Source, Instruction *InsertBefore, +static Instruction *createFree(Value *Source, + ArrayRef<OperandBundleDef> Bundles, + Instruction *InsertBefore, BasicBlock *InsertAtEnd) { assert(((!InsertBefore && InsertAtEnd) || (InsertBefore && !InsertAtEnd)) && "createFree needs either InsertBefore or InsertAtEnd"); @@ -535,11 +557,11 @@ static Instruction *createFree(Value *Source, Instruction *InsertBefore, if (InsertBefore) { if (Source->getType() != IntPtrTy) PtrCast = new BitCastInst(Source, IntPtrTy, "", InsertBefore); - Result = CallInst::Create(FreeFunc, PtrCast, "", InsertBefore); + Result = CallInst::Create(FreeFunc, PtrCast, Bundles, "", InsertBefore); } else { if (Source->getType() != IntPtrTy) PtrCast = new BitCastInst(Source, IntPtrTy, "", InsertAtEnd); - Result = CallInst::Create(FreeFunc, PtrCast, ""); + Result = CallInst::Create(FreeFunc, PtrCast, Bundles, ""); } Result->setTailCall(); if (Function *F = dyn_cast<Function>(FreeFunc)) @@ -550,14 +572,26 @@ static Instruction *createFree(Value *Source, Instruction *InsertBefore, /// CreateFree - Generate the IR for a call to the builtin free function. Instruction *CallInst::CreateFree(Value *Source, Instruction *InsertBefore) { - return createFree(Source, InsertBefore, nullptr); + return createFree(Source, None, InsertBefore, nullptr); +} +Instruction *CallInst::CreateFree(Value *Source, + ArrayRef<OperandBundleDef> Bundles, + Instruction *InsertBefore) { + return createFree(Source, Bundles, InsertBefore, nullptr); } /// CreateFree - Generate the IR for a call to the builtin free function. /// Note: This function does not add the call to the basic block, that is the /// responsibility of the caller. Instruction *CallInst::CreateFree(Value *Source, BasicBlock *InsertAtEnd) { - Instruction *FreeCall = createFree(Source, nullptr, InsertAtEnd); + Instruction *FreeCall = createFree(Source, None, nullptr, InsertAtEnd); + assert(FreeCall && "CreateFree did not create a CallInst"); + return FreeCall; +} +Instruction *CallInst::CreateFree(Value *Source, + ArrayRef<OperandBundleDef> Bundles, + BasicBlock *InsertAtEnd) { + Instruction *FreeCall = createFree(Source, Bundles, nullptr, InsertAtEnd); assert(FreeCall && "CreateFree did not create a CallInst"); return FreeCall; } diff --git a/llvm/lib/Transforms/IPO/GlobalOpt.cpp b/llvm/lib/Transforms/IPO/GlobalOpt.cpp index 05de965c098..e66ed8359ff 100644 --- a/llvm/lib/Transforms/IPO/GlobalOpt.cpp +++ b/llvm/lib/Transforms/IPO/GlobalOpt.cpp @@ -1244,6 +1244,9 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, CallInst *CI, std::vector<Value*> FieldGlobals; std::vector<Value*> FieldMallocs; + SmallVector<OperandBundleDef, 1> OpBundles; + CI->getOperandBundlesAsDefs(OpBundles); + unsigned AS = GV->getType()->getPointerAddressSpace(); for (unsigned FieldNo = 0, e = STy->getNumElements(); FieldNo != e;++FieldNo){ Type *FieldTy = STy->getElementType(FieldNo); @@ -1262,7 +1265,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, CallInst *CI, Type *IntPtrTy = DL.getIntPtrType(CI->getType()); Value *NMI = CallInst::CreateMalloc(CI, IntPtrTy, FieldTy, ConstantInt::get(IntPtrTy, TypeSize), - NElems, nullptr, + NElems, OpBundles, nullptr, CI->getName() + ".f" + Twine(FieldNo)); FieldMallocs.push_back(NMI); new StoreInst(NMI, NGV, CI); @@ -1321,7 +1324,7 @@ static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, CallInst *CI, Cmp, NullPtrBlock); // Fill in FreeBlock. - CallInst::CreateFree(GVVal, BI); + CallInst::CreateFree(GVVal, OpBundles, BI); new StoreInst(Constant::getNullValue(GVVal->getType()), FieldGlobals[i], FreeBlock); BranchInst::Create(NextBlock, FreeBlock); @@ -1487,9 +1490,11 @@ static bool tryToOptimizeStoreOfMallocToGlobal(GlobalVariable *GV, CallInst *CI, unsigned TypeSize = DL.getStructLayout(AllocSTy)->getSizeInBytes(); Value *AllocSize = ConstantInt::get(IntPtrTy, TypeSize); Value *NumElements = ConstantInt::get(IntPtrTy, AT->getNumElements()); - Instruction *Malloc = CallInst::CreateMalloc(CI, IntPtrTy, AllocSTy, - AllocSize, NumElements, - nullptr, CI->getName()); + SmallVector<OperandBundleDef, 1> OpBundles; + CI->getOperandBundlesAsDefs(OpBundles); + Instruction *Malloc = + CallInst::CreateMalloc(CI, IntPtrTy, AllocSTy, AllocSize, NumElements, + OpBundles, nullptr, CI->getName()); Instruction *Cast = new BitCastInst(Malloc, CI->getType(), "tmp", CI); CI->replaceAllUsesWith(Cast); CI->eraseFromParent(); |

