[llvm-commits] [poolalloc] r114670 - in /poolalloc/trunk/lib/PoolAllocate: PoolAllocate.cpp TransformFunctionBody.cpp
John Criswell
criswell at uiuc.edu
Thu Sep 23 10:29:44 PDT 2010
Author: criswell
Date: Thu Sep 23 12:29:43 2010
New Revision: 114670
URL: http://llvm.org/viewvc/llvm-project?rev=114670&view=rev
Log:
Added code to get automatic pool allocation to start playing nice with the new
SAFECode.
Have the poolalloc pass create a poolalloc_init() function because SAFECode
expects there to be one.
Have the poolalloc transform also correctly fill in pool handles into SAFECode
run-time checks.
Added a FIXME of something that needs to be fixed in order to work with
SAFECode correctly.
Modified:
poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp
Modified: poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp?rev=114670&r1=114669&r2=114670&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/PoolAllocate.cpp Thu Sep 23 12:29:43 2010
@@ -82,6 +82,29 @@
}
+static void
+createPoolAllocInit (Module & M) {
+ //
+ // Create the __poolalloc_init() function.
+ //
+ const Type * VoidType = Type::getVoidTy(M.getContext());
+ FunctionType * FTy = FunctionType::get(VoidType,
+ std::vector<const Type*>(),
+ false);
+ Function *InitFunc = Function::Create (FTy,
+ GlobalValue::ExternalLinkage,
+ "__poolalloc_init",
+ &M);
+
+ //
+ // Add an entry basic block that just returns.
+ //
+ BasicBlock * BB = BasicBlock::Create (M.getContext(), "entry", InitFunc);
+ ReturnInst::Create(M.getContext(), BB);
+
+ return;
+}
+
void PoolAllocate::getAnalysisUsage(AnalysisUsage &AU) const {
if (dsa_pass_to_use == PASS_EQTD) {
AU.addRequiredTransitive<EQTDDataStructures>();
@@ -285,6 +308,12 @@
}
//
+ // Add an empty __poolalloc_init() function. SAFECode will call this to
+ // intialize things; we don't make use of it with real pool allocation.
+ //
+ createPoolAllocInit (M);
+
+ //
// FIXME: Make name more descriptive and explain, in a comment here, what this
// code is trying to do (namely, avoid optimizations for performance
// overhead measurements?).
@@ -1316,6 +1345,10 @@
}
}
#else
+ //
+ // FIXME: This is not correct for SAFECode; all DSNodes will need to be
+ // poolallocated.
+ //
if ((N->isHeapNode()) || (BoundsChecksEnabled && (N->isArrayNode())) ||
(GlobalsGraphNodeMapping.count(N) &&
GlobalsGraphNodeMapping[N].getNode()->isHeapNode())) {
@@ -1392,8 +1425,26 @@
void PoolAllocate::CalculateLivePoolFreeBlocks(std::set<BasicBlock*>&LiveBlocks,
Value *PD) {
for (Value::use_iterator I = PD->use_begin(), E = PD->use_end(); I != E; ++I){
- // The only users of the pool should be call & invoke instructions.
- CallSite U = CallSite::get(*I);
+ //
+ // The only users of the pool should be call, invoke, and cast
+ // instructions. We know that poolfree() and pooldestroy() do not need to
+ // cast pool handles, so if we see a non-call instruction, we know it's not
+ // used in a poolfree() or pooldestroy() call.
+ //
+ if (Instruction * Inst = dyn_cast<Instruction>(I)) {
+ if (!isa<CallInst>(*I)) {
+ // This block and every block that can reach this block must keep pool
+ // frees.
+ for (idf_ext_iterator<BasicBlock*, std::set<BasicBlock*> >
+ DI = idf_ext_begin(Inst->getParent(), LiveBlocks),
+ DE = idf_ext_end(Inst->getParent(), LiveBlocks);
+ DI != DE; ++DI)
+ /* empty */;
+ continue;
+ }
+ }
+
+ CallSite U = CallSite::get(I->stripPointerCasts());
if (U.getCalledValue() != PoolFree && U.getCalledValue() != PoolDestroy) {
// This block and every block that can reach this block must keep pool
// frees.
Modified: poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp
URL: http://llvm.org/viewvc/llvm-project/poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp?rev=114670&r1=114669&r2=114670&view=diff
==============================================================================
--- poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp (original)
+++ poolalloc/trunk/lib/PoolAllocate/TransformFunctionBody.cpp Thu Sep 23 12:29:43 2010
@@ -72,6 +72,7 @@
void visitReallocCall(CallSite CS);
void visitMemAlignCall(CallSite CS);
void visitStrdupCall(CallSite CS);
+ void visitRuntimeCheck(CallSite CS);
//void visitFreeInst(FreeInst &FI);
void visitFreeCall(CallSite &CS);
void visitCallSite(CallSite &CS);
@@ -137,6 +138,28 @@
};
}
+static inline Value *
+castTo (Value * V, const Type * Ty, std::string Name, Instruction * InsertPt) {
+ //
+ // Don't bother creating a cast if it's already the correct type.
+ //
+ if (V->getType() == Ty)
+ return V;
+
+ //
+ // If it's a constant, just create a constant expression.
+ //
+ if (Constant * C = dyn_cast<Constant>(V)) {
+ Constant * CE = ConstantExpr::getZExtOrBitCast (C, Ty);
+ return CE;
+ }
+
+ //
+ // Otherwise, insert a cast instruction.
+ //
+ return CastInst::CreateZExtOrBitCast (V, Ty, Name, InsertPt);
+}
+
void
PoolAllocate::TransformBody (DSGraph* g, PA::FuncInfo &fi,
std::multimap<AllocaInst*,Instruction*> &poolUses,
@@ -709,6 +732,40 @@
}
//
+// Method: visitRuntimeCheck()
+//
+// Description:
+// Visit a call to a run-time check (or related function) and insert pool
+// arguments where needed.
+//
+void
+FuncTransform::visitRuntimeCheck (CallSite CS) {
+ // A run-time check should have at least one argument for a pool
+ assert ((CS.arg_size() > 1) && "strdup takes one argument!");
+
+ //
+ // Get the pool handle for the pointer argument.
+ //
+ Value *PH = getPoolHandle(CS.getArgument(1)->stripPointerCasts());
+ //assert (PH && "Pool Handle for run-time checks is null!\n");
+
+ //
+ // Insert the pool handle into the run-time check.
+ //
+ if (PH) {
+ const Type * Int8Type = Type::getInt8Ty(CS.getInstruction()->getContext());
+ const Type * VoidPtrTy = PointerType::getUnqual(Int8Type);
+ PH = castTo (PH, VoidPtrTy, PH->getName(), CS.getInstruction());
+ CS.setArgument (0, PH);
+
+ //
+ // Record that we've used the pool here.
+ //
+ AddPoolUse (*(CS.getInstruction()), PH, PoolUses);
+ }
+}
+
+//
// Method: visitCallSite()
//
// Description:
@@ -780,6 +837,20 @@
} else if (CF->getName() == "valloc") {
errs() << "VALLOC USED BUT NOT HANDLED!\n";
abort();
+ } else if ((CF->getName() == "sc.lscheck") ||
+ (CF->getName() == "sc.lscheckui") ||
+ (CF->getName() == "sc.lscheckalign") ||
+ (CF->getName() == "sc.lscheckalignui") ||
+ (CF->getName() == "sc.boundscheck") ||
+ (CF->getName() == "sc.boundscheckui") ||
+ (CF->getName() == "sc.pool_register_stack") ||
+ (CF->getName() == "sc.pool_unregister_stack") ||
+ (CF->getName() == "sc.pool_register_global") ||
+ (CF->getName() == "sc.pool_unregister_global") ||
+ (CF->getName() == "sc.pool_register") ||
+ (CF->getName() == "sc.pool_unregister") ||
+ (CF->getName() == "sc.get_actual_val")) {
+ visitRuntimeCheck (CS);
} else if (CF->getName() == "pthread_create") {
thread_creation_point = true;
More information about the llvm-commits
mailing list