[llvm] Move CallInst::CreateMalloc to IRBuilderBase::CreateMalloc

This removes `CreateMalloc` from `CallInst` and adds it to the `IRBuilderBase`
class.

We no longer needed the `Instruction *InsertBefore` and
`BasicBlock *InsertAtEnd` arguments of the `createMalloc` helper
function because we're using `IRBuilder` now. That's why I we also don't
need 4 `CreateMalloc` functions, but only two.

Differential Revision: https://reviews.llvm.org/D158861
This commit is contained in:
Konrad Kleine 2023-08-23 16:11:56 +02:00
parent 1d7b59ca8d
commit 45bb45f2ae
9 changed files with 84 additions and 170 deletions

View File

@ -2034,7 +2034,7 @@ val build_switch : llvalue -> llbasicblock -> int -> llbuilder -> llvalue
(** [build_malloc ty name b] creates an [malloc]
instruction at the position specified by the instruction builder [b].
See the method [llvm::CallInst::CreateMalloc]. *)
See the method [llvm::IRBuilderBase::CreateMalloc]. *)
val build_malloc : lltype -> string -> llbuilder -> llvalue
(** [build_array_malloc ty val name b] creates an [array malloc]

View File

@ -94,9 +94,8 @@ void BrainF::header(LLVMContext& C) {
Type* Int8Ty = IntegerType::getInt8Ty(C);
Constant* allocsize = ConstantExpr::getSizeOf(Int8Ty);
allocsize = ConstantExpr::getTruncOrBitCast(allocsize, IntPtrTy);
ptr_arr = CallInst::CreateMalloc(BB, IntPtrTy, Int8Ty, allocsize, val_mem,
nullptr, "arr");
cast<Instruction>(ptr_arr)->insertInto(BB, BB->end());
ptr_arr = builder->CreateMalloc(IntPtrTy, Int8Ty, allocsize, val_mem, nullptr,
"arr");
//call void @llvm.memset.p0i8.i32(i8 *%arr, i8 0, i32 %d, i1 0)
{

View File

@ -619,6 +619,19 @@ public:
TBAATag, ScopeTag, NoAliasTag);
}
CallInst *CreateMalloc(Type *IntPtrTy, Type *AllocTy, Value *AllocSize,
Value *ArraySize, ArrayRef<OperandBundleDef> OpB,
Function *MallocF = nullptr, const Twine &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
/// constant 1.
/// 2. Call malloc with that argument.
CallInst *CreateMalloc(Type *IntPtrTy, Type *AllocTy, Value *AllocSize,
Value *ArraySize, Function *MallocF = nullptr,
const Twine &Name = "");
CallInst *CreateElementUnorderedAtomicMemSet(Value *Ptr, Value *Val,
Value *Size, Align Alignment,
uint32_t ElementSize,

View File

@ -1603,32 +1603,6 @@ public:
static CallInst *Create(CallInst *CI, ArrayRef<OperandBundleDef> Bundles,
Instruction *InsertPt = nullptr);
/// 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
/// constant 1.
/// 2. Call malloc with that argument.
/// 3. Bitcast the result of the malloc call to the specified type.
static Instruction *CreateMalloc(Instruction *InsertBefore, Type *IntPtrTy,
Type *AllocTy, Value *AllocSize,
Value *ArraySize = nullptr,
Function *MallocF = nullptr,
const Twine &Name = "");
static Instruction *CreateMalloc(BasicBlock *InsertAtEnd, Type *IntPtrTy,
Type *AllocTy, 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 = std::nullopt,
Function *MallocF = nullptr, const Twine &Name = "");
static Instruction *
CreateMalloc(BasicBlock *InsertAtEnd, Type *IntPtrTy, Type *AllocTy,
Value *AllocSize, Value *ArraySize = nullptr,
ArrayRef<OperandBundleDef> Bundles = std::nullopt,
Function *MallocF = nullptr, const Twine &Name = "");
/// 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);

View File

@ -3534,10 +3534,8 @@ LLVMValueRef LLVMBuildMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty));
AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy);
Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(),
ITy, unwrap(Ty), AllocSize,
nullptr, nullptr, "");
return wrap(unwrap(B)->Insert(Malloc, Twine(Name)));
return wrap(unwrap(B)->CreateMalloc(ITy, unwrap(Ty), AllocSize, nullptr,
nullptr, Name));
}
LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
@ -3545,10 +3543,8 @@ LLVMValueRef LLVMBuildArrayMalloc(LLVMBuilderRef B, LLVMTypeRef Ty,
Type* ITy = Type::getInt32Ty(unwrap(B)->GetInsertBlock()->getContext());
Constant* AllocSize = ConstantExpr::getSizeOf(unwrap(Ty));
AllocSize = ConstantExpr::getTruncOrBitCast(AllocSize, ITy);
Instruction* Malloc = CallInst::CreateMalloc(unwrap(B)->GetInsertBlock(),
ITy, unwrap(Ty), AllocSize,
unwrap(Val), nullptr, "");
return wrap(unwrap(B)->Insert(Malloc, Twine(Name)));
return wrap(unwrap(B)->CreateMalloc(ITy, unwrap(Ty), AllocSize, unwrap(Val),
nullptr, Name));
}
LLVMValueRef LLVMBuildMemSet(LLVMBuilderRef B, LLVMValueRef Ptr,

View File

@ -291,6 +291,64 @@ CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemCpy(
return CI;
}
/// isConstantOne - Return true only if val is constant int 1
static bool isConstantOne(const Value *Val) {
assert(Val && "isConstantOne does not work with nullptr Val");
const ConstantInt *CVal = dyn_cast<ConstantInt>(Val);
return CVal && CVal->isOne();
}
CallInst *IRBuilderBase::CreateMalloc(Type *IntPtrTy, Type *AllocTy,
Value *AllocSize, Value *ArraySize,
ArrayRef<OperandBundleDef> OpB,
Function *MallocF, const Twine &Name) {
// malloc(type) becomes:
// i8* malloc(typeSize)
// malloc(type, arraySize) becomes:
// i8* malloc(typeSize*arraySize)
if (!ArraySize)
ArraySize = ConstantInt::get(IntPtrTy, 1);
else if (ArraySize->getType() != IntPtrTy)
ArraySize = CreateIntCast(ArraySize, IntPtrTy, false);
if (!isConstantOne(ArraySize)) {
if (isConstantOne(AllocSize)) {
AllocSize = ArraySize; // Operand * 1 = Operand
} else {
// Multiply type size by the array size...
AllocSize = CreateMul(ArraySize, AllocSize, "mallocsize");
}
}
assert(AllocSize->getType() == IntPtrTy && "malloc arg is wrong size");
// Create the call to Malloc.
Module *M = BB->getParent()->getParent();
Type *BPTy = PointerType::getUnqual(Context);
FunctionCallee MallocFunc = MallocF;
if (!MallocFunc)
// prototype malloc as "void *malloc(size_t)"
MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy);
CallInst *MCall = CreateCall(MallocFunc, AllocSize, OpB, Name);
MCall->setTailCall();
if (Function *F = dyn_cast<Function>(MallocFunc.getCallee())) {
MCall->setCallingConv(F->getCallingConv());
F->setReturnDoesNotAlias();
}
assert(!MCall->getType()->isVoidTy() && "Malloc has void return type");
return MCall;
}
CallInst *IRBuilderBase::CreateMalloc(Type *IntPtrTy, Type *AllocTy,
Value *AllocSize, Value *ArraySize,
Function *MallocF, const Twine &Name) {
return CreateMalloc(IntPtrTy, AllocTy, AllocSize, ArraySize, std::nullopt,
MallocF, Name);
}
CallInst *IRBuilderBase::CreateElementUnorderedAtomicMemMove(
Value *Dst, Align DstAlign, Value *Src, Align SrcAlign, Value *Size,
uint32_t ElementSize, MDNode *TBAATag, MDNode *TBAAStructTag,

View File

@ -809,131 +809,6 @@ void CallInst::updateProfWeight(uint64_t S, uint64_t T) {
setMetadata(LLVMContext::MD_prof, MDNode::get(getContext(), Vals));
}
/// IsConstantOne - Return true only if val is constant int 1
static bool IsConstantOne(Value *val) {
assert(val && "IsConstantOne does not work with nullptr val");
const ConstantInt *CVal = dyn_cast<ConstantInt>(val);
return CVal && CVal->isOne();
}
static Instruction *createMalloc(Instruction *InsertBefore,
BasicBlock *InsertAtEnd, Type *IntPtrTy,
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");
// malloc(type) becomes:
// bitcast (i8* malloc(typeSize)) to type*
// malloc(type, arraySize) becomes:
// bitcast (i8* malloc(typeSize*arraySize)) to type*
if (!ArraySize)
ArraySize = ConstantInt::get(IntPtrTy, 1);
else if (ArraySize->getType() != IntPtrTy) {
if (InsertBefore)
ArraySize = CastInst::CreateIntegerCast(ArraySize, IntPtrTy, false,
"", InsertBefore);
else
ArraySize = CastInst::CreateIntegerCast(ArraySize, IntPtrTy, false,
"", InsertAtEnd);
}
if (!IsConstantOne(ArraySize)) {
if (IsConstantOne(AllocSize)) {
AllocSize = ArraySize; // Operand * 1 = Operand
} else if (Constant *CO = dyn_cast<Constant>(ArraySize)) {
Constant *Scale = ConstantExpr::getIntegerCast(CO, IntPtrTy,
false /*ZExt*/);
// Malloc arg is constant product of type size and array size
AllocSize = ConstantExpr::getMul(Scale, cast<Constant>(AllocSize));
} else {
// Multiply type size by the array size...
if (InsertBefore)
AllocSize = BinaryOperator::CreateMul(ArraySize, AllocSize,
"mallocsize", InsertBefore);
else
AllocSize = BinaryOperator::CreateMul(ArraySize, AllocSize,
"mallocsize", InsertAtEnd);
}
}
assert(AllocSize->getType() == IntPtrTy && "malloc arg is wrong size");
// Create the call to Malloc.
BasicBlock *BB = InsertBefore ? InsertBefore->getParent() : InsertAtEnd;
Module *M = BB->getParent()->getParent();
Type *BPTy = PointerType::getUnqual(BB->getContext());
FunctionCallee MallocFunc = MallocF;
if (!MallocFunc)
// prototype malloc as "void *malloc(size_t)"
MallocFunc = M->getOrInsertFunction("malloc", BPTy, IntPtrTy);
CallInst *MCall = nullptr;
if (InsertBefore) {
MCall = CallInst::Create(MallocFunc, AllocSize, OpB, Name,
InsertBefore);
} else {
MCall = CallInst::Create(MallocFunc, AllocSize, OpB, Name);
}
MCall->setTailCall();
if (Function *F = dyn_cast<Function>(MallocFunc.getCallee())) {
MCall->setCallingConv(F->getCallingConv());
if (!F->returnDoesNotAlias())
F->setReturnDoesNotAlias();
}
assert(!MCall->getType()->isVoidTy() && "Malloc has void return type");
return MCall;
}
/// 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
/// constant 1.
/// 2. Call malloc with that argument.
/// 3. Bitcast the result of the malloc call to the specified type.
Instruction *CallInst::CreateMalloc(Instruction *InsertBefore,
Type *IntPtrTy, Type *AllocTy,
Value *AllocSize, Value *ArraySize,
Function *MallocF,
const Twine &Name) {
return createMalloc(InsertBefore, nullptr, IntPtrTy, AllocTy, AllocSize,
ArraySize, std::nullopt, 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
/// constant 1.
/// 2. Call malloc with that argument.
/// 3. Bitcast the result of the malloc call to the specified type.
/// Note: This function does not add the bitcast to the basic block, that is the
/// responsibility of the caller.
Instruction *CallInst::CreateMalloc(BasicBlock *InsertAtEnd,
Type *IntPtrTy, Type *AllocTy,
Value *AllocSize, Value *ArraySize,
Function *MallocF, const Twine &Name) {
return createMalloc(nullptr, InsertAtEnd, IntPtrTy, AllocTy, AllocSize,
ArraySize, std::nullopt, 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,
ArrayRef<OperandBundleDef> Bundles,
Instruction *InsertBefore,

View File

@ -1290,9 +1290,9 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
// setjmpTable = (int *) malloc(40);
Type *IntPtrTy = getAddrIntType(&M);
Constant *size = ConstantInt::get(IntPtrTy, 40);
Instruction *SetjmpTable =
CallInst::CreateMalloc(SetjmpTableSize, IntPtrTy, IRB.getInt32Ty(), size,
nullptr, nullptr, "setjmpTable");
IRB.SetInsertPoint(SetjmpTableSize);
auto *SetjmpTable = IRB.CreateMalloc(IntPtrTy, IRB.getInt32Ty(), size,
nullptr, nullptr, "setjmpTable");
SetjmpTable->setDebugLoc(FirstDL);
// CallInst::CreateMalloc may return a bitcast instruction if the result types
// mismatch. We need to set the debug loc for the original call too.
@ -1301,7 +1301,6 @@ bool WebAssemblyLowerEmscriptenEHSjLj::runSjLjOnFunction(Function &F) {
MallocCallI->setDebugLoc(FirstDL);
}
// setjmpTable[0] = 0;
IRB.SetInsertPoint(SetjmpTableSize);
IRB.CreateStore(IRB.getInt32(0), SetjmpTable);
SetjmpTableInsts.push_back(SetjmpTable);
SetjmpTableSizeInsts.push_back(SetjmpTableSize);

View File

@ -1292,9 +1292,9 @@ void IslNodeBuilder::allocateNewArrays(BBPair StartExitBlocks) {
unsigned Size = SAI->getElemSizeInBytes();
// Insert the malloc call at polly.start
auto InstIt = std::get<0>(StartExitBlocks)->getTerminator();
auto *CreatedArray = CallInst::CreateMalloc(
&*InstIt, IntPtrTy, SAI->getElementType(),
Builder.SetInsertPoint(std::get<0>(StartExitBlocks)->getTerminator());
auto *CreatedArray = Builder.CreateMalloc(
IntPtrTy, SAI->getElementType(),
ConstantInt::get(Type::getInt64Ty(Ctx), Size),
ConstantInt::get(Type::getInt64Ty(Ctx), ArraySizeInt), nullptr,
SAI->getName());