* Change Constant::getNullConstant to Constant::getNullValue

* Add support for pool allocating array allocations of varying size


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@2329 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner 2002-04-27 02:29:32 +00:00
parent ee7eafa054
commit 8e343330a5

View File

@ -250,7 +250,7 @@ namespace {
DataStructure *DS;
// Prototypes that we add to support pool allocation...
Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolFree;
Function *PoolInit, *PoolDestroy, *PoolAlloc, *PoolAllocArray, *PoolFree;
// The map of already transformed functions... note that the keys of this
// map do not have meaningful values for 'Call' or the 'PoolHandle' elements
@ -314,11 +314,6 @@ namespace {
//
static bool isNotPoolableAlloc(const AllocDSNode *DS) {
if (DS->isAllocaNode()) return true; // Do not pool allocate alloca's.
MallocInst *MI = cast<MallocInst>(DS->getAllocation());
if (MI->isArrayAllocation() && !isa<Constant>(MI->getArraySize()))
return true; // Do not allow variable size allocations...
return false;
}
@ -456,7 +451,7 @@ public:
if (isa<Constant>(Ref.OldVal) && // Refering to a null ptr?
cast<Constant>(Ref.OldVal)->isNullValue()) {
// Transform the null pointer into a null index... caching in XFormMap
XFormMap[Ref.OldVal] = NewVal =Constant::getNullConstant(POINTERTYPE);
XFormMap[Ref.OldVal] = NewVal = Constant::getNullValue(POINTERTYPE);
//} else if (isa<Argument>(Ref.OldVal)) {
} else {
cerr << "Unknown reference to: " << Ref.OldVal << "\n";
@ -485,15 +480,16 @@ public:
Instruction *PoolBase = createPoolBaseInstruction(I->getOperand(0));
// Cast our index to be a UIntTy so we can use it to index into the pool...
CastInst *Index = new CastInst(Constant::getNullConstant(POINTERTYPE),
CastInst *Index = new CastInst(Constant::getNullValue(POINTERTYPE),
Type::UIntTy, I->getOperand(0)->getName());
ReferencesToUpdate.push_back(RefToUpdate(Index, 0, I->getOperand(0)));
vector<Value*> Indices(I->idx_begin(), I->idx_end());
assert(Indices[0] == ConstantUInt::get(Type::UIntTy, 0) &&
"Cannot handle array indexing yet!");
Indices[0] = Index;
Instruction *IdxInst =
BinaryOperator::create(Instruction::Add, Indices[0], Index,
I->getName()+".idx");
Indices[0] = IdxInst;
Instruction *NewLoad = new LoadInst(PoolBase, Indices, I->getName());
// Replace the load instruction with the new load instruction...
@ -502,8 +498,11 @@ public:
// Add the pool base calculator instruction before the load...
II = NewLoad->getParent()->getInstList().insert(II, PoolBase) + 1;
// Add the idx calculator instruction before the load...
II = NewLoad->getParent()->getInstList().insert(II, Index) + 1;
// Add the cast before the load instruction...
NewLoad->getParent()->getInstList().insert(II, Index);
NewLoad->getParent()->getInstList().insert(II, IdxInst);
// If not yielding a pool allocated pointer, use the new load value as the
// value in the program instead of the old load value...
@ -523,20 +522,22 @@ public:
Value *Val = I->getOperand(0); // The value to store...
// Check to see if the value we are storing is a data structure pointer...
if (const ScalarInfo *ValScalar = getScalar(I->getOperand(0)))
Val = Constant::getNullConstant(POINTERTYPE); // Yes, store a dummy
//if (const ScalarInfo *ValScalar = getScalar(I->getOperand(0)))
if (isa<PointerType>(I->getOperand(0)->getType()))
Val = Constant::getNullValue(POINTERTYPE); // Yes, store a dummy
Instruction *PoolBase = createPoolBaseInstruction(I->getOperand(1));
// Cast our index to be a UIntTy so we can use it to index into the pool...
CastInst *Index = new CastInst(Constant::getNullConstant(POINTERTYPE),
CastInst *Index = new CastInst(Constant::getNullValue(POINTERTYPE),
Type::UIntTy, I->getOperand(1)->getName());
ReferencesToUpdate.push_back(RefToUpdate(Index, 0, I->getOperand(1)));
vector<Value*> Indices(I->idx_begin(), I->idx_end());
assert(Indices[0] == ConstantUInt::get(Type::UIntTy, 0) &&
"Cannot handle array indexing yet!");
Indices[0] = Index;
Instruction *IdxInst =
BinaryOperator::create(Instruction::Add, Indices[0], Index, "idx");
Indices[0] = IdxInst;
Instruction *NewStore = new StoreInst(Val, PoolBase, Indices);
if (Val != I->getOperand(0)) // Value stored was a pointer?
@ -549,6 +550,9 @@ public:
// Add the pool base calculator instruction before the index...
II = Index->getParent()->getInstList().insert(II, PoolBase) + 2;
// Add the indexing instruction...
II = Index->getParent()->getInstList().insert(II, IdxInst) + 1;
// Add the store after the cast instruction...
Index->getParent()->getInstList().insert(II, NewStore);
}
@ -556,9 +560,19 @@ public:
// Create call to poolalloc for every malloc instruction
void visitMallocInst(MallocInst *I) {
const ScalarInfo &SCI = getScalarRef(I);
vector<Value*> Args;
Args.push_back(getScalarRef(I).Pool.Handle);
CallInst *Call = new CallInst(PoolAllocator.PoolAlloc, Args, I->getName());
CallInst *Call;
if (!I->isArrayAllocation()) {
Args.push_back(SCI.Pool.Handle);
Call = new CallInst(PoolAllocator.PoolAlloc, Args, I->getName());
} else {
Args.push_back(I->getArraySize());
Args.push_back(SCI.Pool.Handle);
Call = new CallInst(PoolAllocator.PoolAllocArray, Args, I->getName());
}
ReplaceInstWith(I, Call);
}
@ -566,7 +580,7 @@ public:
void visitFreeInst(FreeInst *I) {
// Create a new call to poolfree before the free instruction
vector<Value*> Args;
Args.push_back(Constant::getNullConstant(POINTERTYPE));
Args.push_back(Constant::getNullValue(POINTERTYPE));
Args.push_back(getScalarRef(I->getOperand(0)).Pool.Handle);
Instruction *NewCall = new CallInst(PoolAllocator.PoolFree, Args);
ReplaceInstWith(I, NewCall);
@ -585,7 +599,7 @@ public:
for (unsigned i = 0, e = TI.ArgInfo.size(); i != e; ++i) {
// Replace all of the pointer arguments with our new pointer typed values.
if (TI.ArgInfo[i].ArgNo != -1)
Args[TI.ArgInfo[i].ArgNo] = Constant::getNullConstant(POINTERTYPE);
Args[TI.ArgInfo[i].ArgNo] = Constant::getNullValue(POINTERTYPE);
// Add all of the pool arguments...
Args.push_back(TI.ArgInfo[i].PoolHandle);
@ -616,7 +630,7 @@ public:
// nodes...
//
void visitPHINode(PHINode *PN) {
Value *DummyVal = Constant::getNullConstant(POINTERTYPE);
Value *DummyVal = Constant::getNullValue(POINTERTYPE);
PHINode *NewPhi = new PHINode(POINTERTYPE, PN->getName());
for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
NewPhi->addIncoming(DummyVal, PN->getIncomingBlock(i));
@ -629,7 +643,7 @@ public:
// visitReturnInst - Replace ret instruction with a new return...
void visitReturnInst(ReturnInst *I) {
Instruction *Ret = new ReturnInst(Constant::getNullConstant(POINTERTYPE));
Instruction *Ret = new ReturnInst(Constant::getNullValue(POINTERTYPE));
ReplaceInstWith(I, Ret);
ReferencesToUpdate.push_back(RefToUpdate(Ret, 0, I->getOperand(0)));
}
@ -637,7 +651,7 @@ public:
// visitSetCondInst - Replace a conditional test instruction with a new one
void visitSetCondInst(SetCondInst *SCI) {
BinaryOperator *I = (BinaryOperator*)SCI;
Value *DummyVal = Constant::getNullConstant(POINTERTYPE);
Value *DummyVal = Constant::getNullValue(POINTERTYPE);
BinaryOperator *New = BinaryOperator::create(I->getOpcode(), DummyVal,
DummyVal, I->getName());
ReplaceInstWith(I, New);
@ -741,9 +755,9 @@ public:
PoolDescValues.end()) {
assert("Make sure it's a load of the pool base, not a chaining field" &&
LI->getOperand(1) == Constant::getNullConstant(Type::UIntTy) &&
LI->getOperand(2) == Constant::getNullConstant(Type::UByteTy) &&
LI->getOperand(3) == Constant::getNullConstant(Type::UByteTy));
LI->getOperand(1) == Constant::getNullValue(Type::UIntTy) &&
LI->getOperand(2) == Constant::getNullValue(Type::UByteTy) &&
LI->getOperand(3) == Constant::getNullValue(Type::UByteTy));
// If it is a load of a pool base, keep track of it for future reference
PoolDescMap.insert(make_pair(LoadAddr, LI));
@ -1059,7 +1073,7 @@ void PoolAllocate::transformFunctionBody(Function *F, FunctionDSGraph &IPFGraph,
vector<ScalarInfo> Scalars;
#ifdef DEBUG_TRANSFORM_PROGRESS
cerr << "Building scalar map:\n";
cerr << "Building scalar map for fn '" << F->getName() << "' body:\n";
#endif
for (map<Value*, PointerValSet>::iterator I = ValMap.begin(),
@ -1068,6 +1082,7 @@ void PoolAllocate::transformFunctionBody(Function *F, FunctionDSGraph &IPFGraph,
// Check to see if the scalar points to a data structure node...
for (unsigned i = 0, e = PVS.size(); i != e; ++i) {
if (PVS[i].Index) { cerr << "Problem in " << F->getName() << " for " << I->first << "\n"; }
assert(PVS[i].Index == 0 && "Nonzero not handled yet!");
// If the allocation is in the nonescaping set...
@ -1519,14 +1534,14 @@ void PoolAllocate::CreatePools(Function *F, const vector<AllocDSNode*> &Allocs,
// Add a symbol table entry for the new type if there was one for the old
// type...
string OldName = CurModule->getTypeName(Allocs[i]->getType());
if (!OldName.empty())
CurModule->addTypeName(OldName+".p", PI->second.NewType);
if (OldName.empty()) OldName = "node";
CurModule->addTypeName(OldName+".p", PI->second.NewType);
// Create the abstract pool types that will need to be resolved in a second
// pass once an abstract type is created for each pool.
//
// Can only handle limited shapes for now...
StructType *OldNodeTy = cast<StructType>(Allocs[i]->getType());
const Type *OldNodeTy = Allocs[i]->getType();
vector<const Type*> PoolTypes;
// Pool type is the first element of the pool descriptor type...
@ -1542,7 +1557,7 @@ void PoolAllocate::CreatePools(Function *F, const vector<AllocDSNode*> &Allocs,
StructType *PoolType = StructType::get(PoolTypes);
// Add a symbol table entry for the pooltype if possible...
if (!OldName.empty()) CurModule->addTypeName(OldName+".pool", PoolType);
CurModule->addTypeName(OldName+".pool", PoolType);
// Create the pool type, with opaque values for pointers...
AbsPoolTyMap.insert(make_pair(Allocs[i], PoolType));
@ -1686,8 +1701,9 @@ void PoolAllocate::addPoolPrototypes(Module *M) {
FunctionType *PoolFreeTy = FunctionType::get(Type::VoidTy, Args, true);
PoolFree = M->getOrInsertFunction("poolfree", PoolFreeTy);
// Add the %PoolTy type to the symbol table of the module...
//M->addTypeName("PoolTy", PoolTy->getElementType());
Args[0] = Type::UIntTy; // Number of slots to allocate
FunctionType *PoolAllocArrayTy = FunctionType::get(POINTERTYPE, Args, true);
PoolAllocArray = M->getOrInsertFunction("poolallocarray", PoolAllocArrayTy);
}