forked from OSchip/llvm-project
[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:
parent
231a68cc22
commit
fadc6db036
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue