//===-- PoolAllocate.cpp - Pool Allocation Pass ---------------------------===//
//
// This transform changes programs so that disjoint data structures are
// allocated out of different pools of memory, increasing locality and shrinking
// pointer size.
//
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/IPO/PoolAllocate.h"
#include "llvm/Transforms/CloneFunction.h"
#include "llvm/Analysis/DataStructure.h"
#include "llvm/Analysis/DataStructureGraph.h"
#include "llvm/Pass.h"
#include "llvm/Module.h"
#include "llvm/Function.h"
#include "llvm/BasicBlock.h"
#include "llvm/iMemory.h"
#include "llvm/iTerminators.h"
#include "llvm/iPHINode.h"
#include "llvm/iOther.h"
#include "llvm/DerivedTypes.h"
#include "llvm/ConstantVals.h"
#include "llvm/Target/TargetData.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Argument.h"
#include "Support/DepthFirstIterator.h"
#include "Support/STLExtras.h"
#include <algorithm>
// DEBUG_CREATE_POOLS - Enable this to turn on debug output for the pool
// creation phase in the top level function of a transformed data structure.
//
#define DEBUG_CREATE_POOLS 1
const Type *POINTERTYPE;
// FIXME: This is dependant on the sparc backend layout conventions!!
static TargetData TargetData("test");
namespace {
struct PoolInfo {
DSNode *Node; // The node this pool allocation represents
Value *Handle; // LLVM value of the pool in the current context
const Type *NewType; // The transformed type of the memory objects
const Type *PoolType; // The type of the pool
const Type *getOldType() const { return Node->getType(); }
PoolInfo() { // Define a default ctor for map::operator[]
cerr << "Map subscript used to get element that doesn't exist!\n";
abort(); // Invalid
}
PoolInfo(DSNode *N, Value *H, const Type *NT, const Type *PT)
: Node(N), Handle(H), NewType(NT), PoolType(PT) {
// Handle can be null...
assert(N && NT && PT && "Pool info null!");
}
PoolInfo(DSNode *N) : Node(N), Handle(0), NewType(0), PoolType(0) {
assert(N && "Invalid pool info!");
// The new type of the memory object is the same as the old type, except
// that all of the pointer values are replaced with POINTERTYPE values.
assert(isa<StructType>(getOldType()) && "Can only handle structs!");
StructType *OldTy = cast<StructType>(getOldType());
vector<const Type *> NewElTypes;
NewElTypes.reserve(OldTy->getElementTypes().size());
for (StructType::ElementTypes::const_iterator
I = OldTy->getElementTypes().begin(),
E = OldTy->getElementTypes().end(); I != E; ++I)
if (PointerType *PT =