//
// The LLVM Compiler Infrastructure
//
-// This file was developed by the LLVM research group and is distributed under
-// the University of Illinois Open Source License. See LICENSE.TXT for details.
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//
+#define DEBUG_TYPE "lowerallocs"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/UnifyFunctionExitNodes.h"
#include "llvm/Module.h"
#include "llvm/Support/Compiler.h"
using namespace llvm;
-namespace {
- Statistic NumLowered("lowerallocs", "Number of allocations lowered");
+STATISTIC(NumLowered, "Number of allocations lowered");
+namespace {
/// LowerAllocations - Turn malloc and free instructions into %malloc and
/// %free calls.
///
class VISIBILITY_HIDDEN LowerAllocations : public BasicBlockPass {
- Function *MallocFunc; // Functions in the module we are processing
- Function *FreeFunc; // Initialized by doInitialization
+ Constant *MallocFunc; // Functions in the module we are processing
+ Constant *FreeFunc; // Initialized by doInitialization
bool LowerMallocArgToInteger;
public:
- LowerAllocations(bool LowerToInt = false)
- : MallocFunc(0), FreeFunc(0), LowerMallocArgToInteger(LowerToInt) {}
+ static char ID; // Pass ID, replacement for typeid
+ explicit LowerAllocations(bool LowerToInt = false)
+ : BasicBlockPass((intptr_t)&ID), MallocFunc(0), FreeFunc(0),
+ LowerMallocArgToInteger(LowerToInt) {}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
AU.addRequired<TargetData>();
AU.setPreservesCFG();
- // This is a cluster of orthogonal Transforms:
+ // This is a cluster of orthogonal Transforms:
AU.addPreserved<UnifyFunctionExitNodes>();
AU.addPreservedID(PromoteMemoryToRegisterID);
- AU.addPreservedID(LowerSelectID);
AU.addPreservedID(LowerSwitchID);
AU.addPreservedID(LowerInvokePassID);
}
bool runOnBasicBlock(BasicBlock &BB);
};
+ char LowerAllocations::ID = 0;
RegisterPass<LowerAllocations>
X("lowerallocs", "Lower allocations from instructions to calls");
}
// Publically exposed interface to pass...
const PassInfo *llvm::LowerAllocationsID = X.getPassInfo();
// createLowerAllocationsPass - Interface to this file...
-FunctionPass *llvm::createLowerAllocationsPass(bool LowerMallocArgToInteger) {
+Pass *llvm::createLowerAllocationsPass(bool LowerMallocArgToInteger) {
return new LowerAllocations(LowerMallocArgToInteger);
}
// This function is always successful.
//
bool LowerAllocations::doInitialization(Module &M) {
- const Type *SBPTy = PointerType::get(Type::SByteTy);
- MallocFunc = M.getNamedFunction("malloc");
- FreeFunc = M.getNamedFunction("free");
-
- if (MallocFunc == 0) {
- // Prototype malloc as "void* malloc(...)", because we don't know in
- // doInitialization whether size_t is int or long.
- FunctionType *FT = FunctionType::get(SBPTy,std::vector<const Type*>(),true);
- MallocFunc = M.getOrInsertFunction("malloc", FT);
- }
- if (FreeFunc == 0)
- FreeFunc = M.getOrInsertFunction("free" , Type::VoidTy, SBPTy, (Type *)0);
-
+ const Type *BPTy = PointerType::getUnqual(Type::Int8Ty);
+ // Prototype malloc as "char* malloc(...)", because we don't know in
+ // doInitialization whether size_t is int or long.
+ FunctionType *FT = FunctionType::get(BPTy, std::vector<const Type*>(), true);
+ MallocFunc = M.getOrInsertFunction("malloc", FT);
+ FreeFunc = M.getOrInsertFunction("free" , Type::VoidTy, BPTy, (Type *)0);
return true;
}
// malloc(type) becomes sbyte *malloc(size)
Value *MallocArg;
if (LowerMallocArgToInteger)
- MallocArg = ConstantInt::get(Type::ULongTy, TD.getTypeSize(AllocTy));
+ MallocArg = ConstantInt::get(Type::Int64Ty, TD.getABITypeSize(AllocTy));
else
MallocArg = ConstantExpr::getSizeOf(AllocTy);
MallocArg = ConstantExpr::getTruncOrBitCast(cast<Constant>(MallocArg),
if (MI->isArrayAllocation()) {
if (isa<ConstantInt>(MallocArg) &&
- cast<ConstantInt>(MallocArg)->getZExtValue() == 1) {
+ cast<ConstantInt>(MallocArg)->isOne()) {
MallocArg = MI->getOperand(0); // Operand * 1 = Operand
} else if (Constant *CO = dyn_cast<Constant>(MI->getOperand(0))) {
CO = ConstantExpr::getIntegerCast(CO, IntPtrTy, false /*ZExt*/);
} else {
Value *Scale = MI->getOperand(0);
if (Scale->getType() != IntPtrTy)
- Scale = CastInst::createInferredCast(Scale, IntPtrTy, "", I);
+ Scale = CastInst::createIntegerCast(Scale, IntPtrTy, false /*ZExt*/,
+ "", I);
// Multiply it by the array size if necessary...
MallocArg = BinaryOperator::create(Instruction::Mul, Scale,
}
}
- const FunctionType *MallocFTy = MallocFunc->getFunctionType();
- std::vector<Value*> MallocArgs;
-
- if (MallocFTy->getNumParams() > 0 || MallocFTy->isVarArg()) {
- if (MallocFTy->isVarArg()) {
- if (MallocArg->getType() != IntPtrTy)
- MallocArg = CastInst::createInferredCast(MallocArg, IntPtrTy, "",
- I);
- } else if (MallocFTy->getNumParams() > 0 &&
- MallocFTy->getParamType(0) != Type::UIntTy)
- MallocArg =
- CastInst::createInferredCast(MallocArg, MallocFTy->getParamType(0),
- "",I);
- MallocArgs.push_back(MallocArg);
- }
-
- // If malloc is prototyped to take extra arguments, pass nulls.
- for (unsigned i = 1; i < MallocFTy->getNumParams(); ++i)
- MallocArgs.push_back(Constant::getNullValue(MallocFTy->getParamType(i)));
-
- // Create the call to Malloc...
- CallInst *MCall = new CallInst(MallocFunc, MallocArgs, "", I);
+ // Create the call to Malloc.
+ CallInst *MCall = new CallInst(MallocFunc, MallocArg, "", I);
MCall->setTailCall();
// Create a cast instruction to convert to the right type...
Value *MCast;
if (MCall->getType() != Type::VoidTy)
- MCast = CastInst::createInferredCast(MCall, MI->getType(), "", I);
+ MCast = new BitCastInst(MCall, MI->getType(), "", I);
else
MCast = Constant::getNullValue(MI->getType());
Changed = true;
++NumLowered;
} else if (FreeInst *FI = dyn_cast<FreeInst>(I)) {
- const FunctionType *FreeFTy = FreeFunc->getFunctionType();
- std::vector<Value*> FreeArgs;
-
- if (FreeFTy->getNumParams() > 0 || FreeFTy->isVarArg()) {
- Value *MCast = FI->getOperand(0);
- if (FreeFTy->getNumParams() > 0 &&
- FreeFTy->getParamType(0) != MCast->getType())
- MCast = CastInst::createInferredCast(MCast, FreeFTy->getParamType(0),
- "", I);
- FreeArgs.push_back(MCast);
- }
-
- // If malloc is prototyped to take extra arguments, pass nulls.
- for (unsigned i = 1; i < FreeFTy->getNumParams(); ++i)
- FreeArgs.push_back(Constant::getNullValue(FreeFTy->getParamType(i)));
+ Value *PtrCast =
+ new BitCastInst(FI->getOperand(0),
+ PointerType::getUnqual(Type::Int8Ty), "", I);
// Insert a call to the free function...
- (new CallInst(FreeFunc, FreeArgs, "", I))->setTailCall();
+ (new CallInst(FreeFunc, PtrCast, "", I))->setTailCall();
// Delete the old free instruction
I = --BBIL.erase(I);