[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
This commit is contained in:
David Majnemer 2016-04-29 08:07:22 +00:00
parent 231a68cc22
commit fadc6db036
3 changed files with 78 additions and 19 deletions

View File

@ -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;

View File

@ -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,8 +499,18 @@ 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,
@ -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;
}

View File

@ -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();