aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Transforms/IPO
diff options
context:
space:
mode:
authorDan Gohman <djg@cray.com>2007-07-18 16:29:46 +0000
committerDan Gohman <djg@cray.com>2007-07-18 16:29:46 +0000
commitf17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc (patch)
treeebb79ea1ee5e3bc1fdf38541a811a8b804f0679a /lib/Transforms/IPO
downloadexternal_llvm-f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc.zip
external_llvm-f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc.tar.gz
external_llvm-f17a25c88b892d30c2b41ba7ecdfbdfb2b4be9cc.tar.bz2
It's not necessary to do rounding for alloca operations when the requested
alignment is equal to the stack alignment. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@40004 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Transforms/IPO')
-rw-r--r--lib/Transforms/IPO/ArgumentPromotion.cpp559
-rw-r--r--lib/Transforms/IPO/ConstantMerge.cpp116
-rw-r--r--lib/Transforms/IPO/DeadArgumentElimination.cpp703
-rw-r--r--lib/Transforms/IPO/DeadTypeElimination.cpp106
-rw-r--r--lib/Transforms/IPO/ExtractFunction.cpp144
-rw-r--r--lib/Transforms/IPO/GlobalDCE.cpp203
-rw-r--r--lib/Transforms/IPO/GlobalOpt.cpp1988
-rw-r--r--lib/Transforms/IPO/IPConstantPropagation.cpp197
-rw-r--r--lib/Transforms/IPO/IndMemRemoval.cpp89
-rw-r--r--lib/Transforms/IPO/InlineSimple.cpp323
-rw-r--r--lib/Transforms/IPO/Inliner.cpp217
-rw-r--r--lib/Transforms/IPO/Internalize.cpp154
-rw-r--r--lib/Transforms/IPO/LoopExtractor.cpp201
-rw-r--r--lib/Transforms/IPO/LowerSetJmp.cpp534
-rw-r--r--lib/Transforms/IPO/Makefile15
-rw-r--r--lib/Transforms/IPO/PruneEH.cpp233
-rw-r--r--lib/Transforms/IPO/RaiseAllocations.cpp249
-rw-r--r--lib/Transforms/IPO/SimplifyLibCalls.cpp2021
-rw-r--r--lib/Transforms/IPO/StripDeadPrototypes.cpp70
-rw-r--r--lib/Transforms/IPO/StripSymbols.cpp206
20 files changed, 8328 insertions, 0 deletions
diff --git a/lib/Transforms/IPO/ArgumentPromotion.cpp b/lib/Transforms/IPO/ArgumentPromotion.cpp
new file mode 100644
index 0000000..9a7bcc7
--- /dev/null
+++ b/lib/Transforms/IPO/ArgumentPromotion.cpp
@@ -0,0 +1,559 @@
+//===-- ArgumentPromotion.cpp - Promote by-reference arguments ------------===//
+//
+// 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 pass promotes "by reference" arguments to be "by value" arguments. In
+// practice, this means looking for internal functions that have pointer
+// arguments. If we can prove, through the use of alias analysis, that an
+// argument is *only* loaded, then we can pass the value into the function
+// instead of the address of the value. This can cause recursive simplification
+// of code and lead to the elimination of allocas (especially in C++ template
+// code like the STL).
+//
+// This pass also handles aggregate arguments that are passed into a function,
+// scalarizing them if the elements of the aggregate are only loaded. Note that
+// we refuse to scalarize aggregates which would require passing in more than
+// three operands to the function, because we don't want to pass thousands of
+// operands for a large array or structure!
+//
+// Note that this transformation could also be done for arguments that are only
+// stored to (returning the value instead), but we do not currently handle that
+// case. This case would be best handled when and if we start supporting
+// multiple return values from functions.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "argpromotion"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/CallGraphSCCPass.h"
+#include "llvm/Instructions.h"
+#include "llvm/Analysis/AliasAnalysis.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/Support/Compiler.h"
+#include <set>
+using namespace llvm;
+
+STATISTIC(NumArgumentsPromoted , "Number of pointer arguments promoted");
+STATISTIC(NumAggregatesPromoted, "Number of aggregate arguments promoted");
+STATISTIC(NumArgumentsDead , "Number of dead pointer args eliminated");
+
+namespace {
+ /// ArgPromotion - The 'by reference' to 'by value' argument promotion pass.
+ ///
+ struct VISIBILITY_HIDDEN ArgPromotion : public CallGraphSCCPass {
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<AliasAnalysis>();
+ AU.addRequired<TargetData>();
+ CallGraphSCCPass::getAnalysisUsage(AU);
+ }
+
+ virtual bool runOnSCC(const std::vector<CallGraphNode *> &SCC);
+ static char ID; // Pass identification, replacement for typeid
+ ArgPromotion() : CallGraphSCCPass((intptr_t)&ID) {}
+
+ private:
+ bool PromoteArguments(CallGraphNode *CGN);
+ bool isSafeToPromoteArgument(Argument *Arg) const;
+ Function *DoPromotion(Function *F, std::vector<Argument*> &ArgsToPromote);
+ };
+
+ char ArgPromotion::ID = 0;
+ RegisterPass<ArgPromotion> X("argpromotion",
+ "Promote 'by reference' arguments to scalars");
+}
+
+Pass *llvm::createArgumentPromotionPass() {
+ return new ArgPromotion();
+}
+
+bool ArgPromotion::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
+ bool Changed = false, LocalChange;
+
+ do { // Iterate until we stop promoting from this SCC.
+ LocalChange = false;
+ // Attempt to promote arguments from all functions in this SCC.
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i)
+ LocalChange |= PromoteArguments(SCC[i]);
+ Changed |= LocalChange; // Remember that we changed something.
+ } while (LocalChange);
+
+ return Changed;
+}
+
+/// PromoteArguments - This method checks the specified function to see if there
+/// are any promotable arguments and if it is safe to promote the function (for
+/// example, all callers are direct). If safe to promote some arguments, it
+/// calls the DoPromotion method.
+///
+bool ArgPromotion::PromoteArguments(CallGraphNode *CGN) {
+ Function *F = CGN->getFunction();
+
+ // Make sure that it is local to this module.
+ if (!F || !F->hasInternalLinkage()) return false;
+
+ // First check: see if there are any pointer arguments! If not, quick exit.
+ std::vector<Argument*> PointerArgs;
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+ if (isa<PointerType>(I->getType()))
+ PointerArgs.push_back(I);
+ if (PointerArgs.empty()) return false;
+
+ // Second check: make sure that all callers are direct callers. We can't
+ // transform functions that have indirect callers.
+ for (Value::use_iterator UI = F->use_begin(), E = F->use_end();
+ UI != E; ++UI) {
+ CallSite CS = CallSite::get(*UI);
+ if (!CS.getInstruction()) // "Taking the address" of the function
+ return false;
+
+ // Ensure that this call site is CALLING the function, not passing it as
+ // an argument.
+ for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
+ AI != E; ++AI)
+ if (*AI == F) return false; // Passing the function address in!
+ }
+
+ // Check to see which arguments are promotable. If an argument is not
+ // promotable, remove it from the PointerArgs vector.
+ for (unsigned i = 0; i != PointerArgs.size(); ++i)
+ if (!isSafeToPromoteArgument(PointerArgs[i])) {
+ std::swap(PointerArgs[i--], PointerArgs.back());
+ PointerArgs.pop_back();
+ }
+
+ // No promotable pointer arguments.
+ if (PointerArgs.empty()) return false;
+
+ // Okay, promote all of the arguments are rewrite the callees!
+ Function *NewF = DoPromotion(F, PointerArgs);
+
+ // Update the call graph to know that the old function is gone.
+ getAnalysis<CallGraph>().changeFunction(F, NewF);
+ return true;
+}
+
+/// IsAlwaysValidPointer - Return true if the specified pointer is always legal
+/// to load.
+static bool IsAlwaysValidPointer(Value *V) {
+ if (isa<AllocaInst>(V) || isa<GlobalVariable>(V)) return true;
+ if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(V))
+ return IsAlwaysValidPointer(GEP->getOperand(0));
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V))
+ if (CE->getOpcode() == Instruction::GetElementPtr)
+ return IsAlwaysValidPointer(CE->getOperand(0));
+
+ return false;
+}
+
+/// AllCalleesPassInValidPointerForArgument - Return true if we can prove that
+/// all callees pass in a valid pointer for the specified function argument.
+static bool AllCalleesPassInValidPointerForArgument(Argument *Arg) {
+ Function *Callee = Arg->getParent();
+
+ unsigned ArgNo = std::distance(Callee->arg_begin(),
+ Function::arg_iterator(Arg));
+
+ // Look at all call sites of the function. At this pointer we know we only
+ // have direct callees.
+ for (Value::use_iterator UI = Callee->use_begin(), E = Callee->use_end();
+ UI != E; ++UI) {
+ CallSite CS = CallSite::get(*UI);
+ assert(CS.getInstruction() && "Should only have direct calls!");
+
+ if (!IsAlwaysValidPointer(CS.getArgument(ArgNo)))
+ return false;
+ }
+ return true;
+}
+
+
+/// isSafeToPromoteArgument - As you might guess from the name of this method,
+/// it checks to see if it is both safe and useful to promote the argument.
+/// This method limits promotion of aggregates to only promote up to three
+/// elements of the aggregate in order to avoid exploding the number of
+/// arguments passed in.
+bool ArgPromotion::isSafeToPromoteArgument(Argument *Arg) const {
+ // We can only promote this argument if all of the uses are loads, or are GEP
+ // instructions (with constant indices) that are subsequently loaded.
+ bool HasLoadInEntryBlock = false;
+ BasicBlock *EntryBlock = Arg->getParent()->begin();
+ std::vector<LoadInst*> Loads;
+ std::vector<std::vector<ConstantInt*> > GEPIndices;
+ for (Value::use_iterator UI = Arg->use_begin(), E = Arg->use_end();
+ UI != E; ++UI)
+ if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) {
+ if (LI->isVolatile()) return false; // Don't hack volatile loads
+ Loads.push_back(LI);
+ HasLoadInEntryBlock |= LI->getParent() == EntryBlock;
+ } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(*UI)) {
+ if (GEP->use_empty()) {
+ // Dead GEP's cause trouble later. Just remove them if we run into
+ // them.
+ getAnalysis<AliasAnalysis>().deleteValue(GEP);
+ GEP->getParent()->getInstList().erase(GEP);
+ return isSafeToPromoteArgument(Arg);
+ }
+ // Ensure that all of the indices are constants.
+ std::vector<ConstantInt*> Operands;
+ for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
+ if (ConstantInt *C = dyn_cast<ConstantInt>(GEP->getOperand(i)))
+ Operands.push_back(C);
+ else
+ return false; // Not a constant operand GEP!
+
+ // Ensure that the only users of the GEP are load instructions.
+ for (Value::use_iterator UI = GEP->use_begin(), E = GEP->use_end();
+ UI != E; ++UI)
+ if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) {
+ if (LI->isVolatile()) return false; // Don't hack volatile loads
+ Loads.push_back(LI);
+ HasLoadInEntryBlock |= LI->getParent() == EntryBlock;
+ } else {
+ return false;
+ }
+
+ // See if there is already a GEP with these indices. If not, check to
+ // make sure that we aren't promoting too many elements. If so, nothing
+ // to do.
+ if (std::find(GEPIndices.begin(), GEPIndices.end(), Operands) ==
+ GEPIndices.end()) {
+ if (GEPIndices.size() == 3) {
+ DOUT << "argpromotion disable promoting argument '"
+ << Arg->getName() << "' because it would require adding more "
+ << "than 3 arguments to the function.\n";
+ // We limit aggregate promotion to only promoting up to three elements
+ // of the aggregate.
+ return false;
+ }
+ GEPIndices.push_back(Operands);
+ }
+ } else {
+ return false; // Not a load or a GEP.
+ }
+
+ if (Loads.empty()) return true; // No users, this is a dead argument.
+
+ // If we decide that we want to promote this argument, the value is going to
+ // be unconditionally loaded in all callees. This is only safe to do if the
+ // pointer was going to be unconditionally loaded anyway (i.e. there is a load
+ // of the pointer in the entry block of the function) or if we can prove that
+ // all pointers passed in are always to legal locations (for example, no null
+ // pointers are passed in, no pointers to free'd memory, etc).
+ if (!HasLoadInEntryBlock && !AllCalleesPassInValidPointerForArgument(Arg))
+ return false; // Cannot prove that this is safe!!
+
+ // Okay, now we know that the argument is only used by load instructions and
+ // it is safe to unconditionally load the pointer. Use alias analysis to
+ // check to see if the pointer is guaranteed to not be modified from entry of
+ // the function to each of the load instructions.
+
+ // Because there could be several/many load instructions, remember which
+ // blocks we know to be transparent to the load.
+ std::set<BasicBlock*> TranspBlocks;
+
+ AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+ TargetData &TD = getAnalysis<TargetData>();
+
+ for (unsigned i = 0, e = Loads.size(); i != e; ++i) {
+ // Check to see if the load is invalidated from the start of the block to
+ // the load itself.
+ LoadInst *Load = Loads[i];
+ BasicBlock *BB = Load->getParent();
+
+ const PointerType *LoadTy =
+ cast<PointerType>(Load->getOperand(0)->getType());
+ unsigned LoadSize = (unsigned)TD.getTypeSize(LoadTy->getElementType());
+
+ if (AA.canInstructionRangeModify(BB->front(), *Load, Arg, LoadSize))
+ return false; // Pointer is invalidated!
+
+ // Now check every path from the entry block to the load for transparency.
+ // To do this, we perform a depth first search on the inverse CFG from the
+ // loading block.
+ for (pred_iterator PI = pred_begin(BB), E = pred_end(BB); PI != E; ++PI)
+ for (idf_ext_iterator<BasicBlock*> I = idf_ext_begin(*PI, TranspBlocks),
+ E = idf_ext_end(*PI, TranspBlocks); I != E; ++I)
+ if (AA.canBasicBlockModify(**I, Arg, LoadSize))
+ return false;
+ }
+
+ // If the path from the entry of the function to each load is free of
+ // instructions that potentially invalidate the load, we can make the
+ // transformation!
+ return true;
+}
+
+namespace {
+ /// GEPIdxComparator - Provide a strong ordering for GEP indices. All Value*
+ /// elements are instances of ConstantInt.
+ ///
+ struct GEPIdxComparator {
+ bool operator()(const std::vector<Value*> &LHS,
+ const std::vector<Value*> &RHS) const {
+ unsigned idx = 0;
+ for (; idx < LHS.size() && idx < RHS.size(); ++idx) {
+ if (LHS[idx] != RHS[idx]) {
+ return cast<ConstantInt>(LHS[idx])->getZExtValue() <
+ cast<ConstantInt>(RHS[idx])->getZExtValue();
+ }
+ }
+
+ // Return less than if we ran out of stuff in LHS and we didn't run out of
+ // stuff in RHS.
+ return idx == LHS.size() && idx != RHS.size();
+ }
+ };
+}
+
+
+/// DoPromotion - This method actually performs the promotion of the specified
+/// arguments, and returns the new function. At this point, we know that it's
+/// safe to do so.
+Function *ArgPromotion::DoPromotion(Function *F,
+ std::vector<Argument*> &Args2Prom) {
+ std::set<Argument*> ArgsToPromote(Args2Prom.begin(), Args2Prom.end());
+
+ // Start by computing a new prototype for the function, which is the same as
+ // the old function, but has modified arguments.
+ const FunctionType *FTy = F->getFunctionType();
+ std::vector<const Type*> Params;
+
+ typedef std::set<std::vector<Value*>, GEPIdxComparator> ScalarizeTable;
+
+ // ScalarizedElements - If we are promoting a pointer that has elements
+ // accessed out of it, keep track of which elements are accessed so that we
+ // can add one argument for each.
+ //
+ // Arguments that are directly loaded will have a zero element value here, to
+ // handle cases where there are both a direct load and GEP accesses.
+ //
+ std::map<Argument*, ScalarizeTable> ScalarizedElements;
+
+ // OriginalLoads - Keep track of a representative load instruction from the
+ // original function so that we can tell the alias analysis implementation
+ // what the new GEP/Load instructions we are inserting look like.
+ std::map<std::vector<Value*>, LoadInst*> OriginalLoads;
+
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+ if (!ArgsToPromote.count(I)) {
+ Params.push_back(I->getType());
+ } else if (I->use_empty()) {
+ ++NumArgumentsDead;
+ } else {
+ // Okay, this is being promoted. Check to see if there are any GEP uses
+ // of the argument.
+ ScalarizeTable &ArgIndices = ScalarizedElements[I];
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end(); UI != E;
+ ++UI) {
+ Instruction *User = cast<Instruction>(*UI);
+ assert(isa<LoadInst>(User) || isa<GetElementPtrInst>(User));
+ std::vector<Value*> Indices(User->op_begin()+1, User->op_end());
+ ArgIndices.insert(Indices);
+ LoadInst *OrigLoad;
+ if (LoadInst *L = dyn_cast<LoadInst>(User))
+ OrigLoad = L;
+ else
+ OrigLoad = cast<LoadInst>(User->use_back());
+ OriginalLoads[Indices] = OrigLoad;
+ }
+
+ // Add a parameter to the function for each element passed in.
+ for (ScalarizeTable::iterator SI = ArgIndices.begin(),
+ E = ArgIndices.end(); SI != E; ++SI)
+ Params.push_back(GetElementPtrInst::getIndexedType(I->getType(),
+ &(*SI)[0],
+ SI->size()));
+
+ if (ArgIndices.size() == 1 && ArgIndices.begin()->empty())
+ ++NumArgumentsPromoted;
+ else
+ ++NumAggregatesPromoted;
+ }
+
+ const Type *RetTy = FTy->getReturnType();
+
+ // Work around LLVM bug PR56: the CWriter cannot emit varargs functions which
+ // have zero fixed arguments.
+ bool ExtraArgHack = false;
+ if (Params.empty() && FTy->isVarArg()) {
+ ExtraArgHack = true;
+ Params.push_back(Type::Int32Ty);
+ }
+ FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg());
+
+ // Create the new function body and insert it into the module...
+ Function *NF = new Function(NFTy, F->getLinkage(), F->getName());
+ NF->setCallingConv(F->getCallingConv());
+ F->getParent()->getFunctionList().insert(F, NF);
+
+ // Get the alias analysis information that we need to update to reflect our
+ // changes.
+ AliasAnalysis &AA = getAnalysis<AliasAnalysis>();
+
+ // Loop over all of the callers of the function, transforming the call sites
+ // to pass in the loaded pointers.
+ //
+ std::vector<Value*> Args;
+ while (!F->use_empty()) {
+ CallSite CS = CallSite::get(F->use_back());
+ Instruction *Call = CS.getInstruction();
+
+ // Loop over the operands, inserting GEP and loads in the caller as
+ // appropriate.
+ CallSite::arg_iterator AI = CS.arg_begin();
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
+ I != E; ++I, ++AI)
+ if (!ArgsToPromote.count(I))
+ Args.push_back(*AI); // Unmodified argument
+ else if (!I->use_empty()) {
+ // Non-dead argument: insert GEPs and loads as appropriate.
+ ScalarizeTable &ArgIndices = ScalarizedElements[I];
+ for (ScalarizeTable::iterator SI = ArgIndices.begin(),
+ E = ArgIndices.end(); SI != E; ++SI) {
+ Value *V = *AI;
+ LoadInst *OrigLoad = OriginalLoads[*SI];
+ if (!SI->empty()) {
+ V = new GetElementPtrInst(V, &(*SI)[0], SI->size(),
+ V->getName()+".idx", Call);
+ AA.copyValue(OrigLoad->getOperand(0), V);
+ }
+ Args.push_back(new LoadInst(V, V->getName()+".val", Call));
+ AA.copyValue(OrigLoad, Args.back());
+ }
+ }
+
+ if (ExtraArgHack)
+ Args.push_back(Constant::getNullValue(Type::Int32Ty));
+
+ // Push any varargs arguments on the list
+ for (; AI != CS.arg_end(); ++AI)
+ Args.push_back(*AI);
+
+ Instruction *New;
+ if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
+ New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
+ &Args[0], Args.size(), "", Call);
+ cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
+ } else {
+ New = new CallInst(NF, &Args[0], Args.size(), "", Call);
+ cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
+ if (cast<CallInst>(Call)->isTailCall())
+ cast<CallInst>(New)->setTailCall();
+ }
+ Args.clear();
+
+ // Update the alias analysis implementation to know that we are replacing
+ // the old call with a new one.
+ AA.replaceWithNewValue(Call, New);
+
+ if (!Call->use_empty()) {
+ Call->replaceAllUsesWith(New);
+ New->takeName(Call);
+ }
+
+ // Finally, remove the old call from the program, reducing the use-count of
+ // F.
+ Call->getParent()->getInstList().erase(Call);
+ }
+
+ // Since we have now created the new function, splice the body of the old
+ // function right into the new function, leaving the old rotting hulk of the
+ // function empty.
+ NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());
+
+ // Loop over the argument list, transfering uses of the old arguments over to
+ // the new arguments, also transfering over the names as well.
+ //
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(),
+ I2 = NF->arg_begin(); I != E; ++I)
+ if (!ArgsToPromote.count(I)) {
+ // If this is an unmodified argument, move the name and users over to the
+ // new version.
+ I->replaceAllUsesWith(I2);
+ I2->takeName(I);
+ AA.replaceWithNewValue(I, I2);
+ ++I2;
+ } else if (I->use_empty()) {
+ AA.deleteValue(I);
+ } else {
+ // Otherwise, if we promoted this argument, then all users are load
+ // instructions, and all loads should be using the new argument that we
+ // added.
+ ScalarizeTable &ArgIndices = ScalarizedElements[I];
+
+ while (!I->use_empty()) {
+ if (LoadInst *LI = dyn_cast<LoadInst>(I->use_back())) {
+ assert(ArgIndices.begin()->empty() &&
+ "Load element should sort to front!");
+ I2->setName(I->getName()+".val");
+ LI->replaceAllUsesWith(I2);
+ AA.replaceWithNewValue(LI, I2);
+ LI->getParent()->getInstList().erase(LI);
+ DOUT << "*** Promoted load of argument '" << I->getName()
+ << "' in function '" << F->getName() << "'\n";
+ } else {
+ GetElementPtrInst *GEP = cast<GetElementPtrInst>(I->use_back());
+ std::vector<Value*> Operands(GEP->op_begin()+1, GEP->op_end());
+
+ Function::arg_iterator TheArg = I2;
+ for (ScalarizeTable::iterator It = ArgIndices.begin();
+ *It != Operands; ++It, ++TheArg) {
+ assert(It != ArgIndices.end() && "GEP not handled??");
+ }
+
+ std::string NewName = I->getName();
+ for (unsigned i = 0, e = Operands.size(); i != e; ++i)
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(Operands[i]))
+ NewName += "." + CI->getValue().toString(10);
+ else
+ NewName += ".x";
+ TheArg->setName(NewName+".val");
+
+ DOUT << "*** Promoted agg argument '" << TheArg->getName()
+ << "' of function '" << F->getName() << "'\n";
+
+ // All of the uses must be load instructions. Replace them all with
+ // the argument specified by ArgNo.
+ while (!GEP->use_empty()) {
+ LoadInst *L = cast<LoadInst>(GEP->use_back());
+ L->replaceAllUsesWith(TheArg);
+ AA.replaceWithNewValue(L, TheArg);
+ L->getParent()->getInstList().erase(L);
+ }
+ AA.deleteValue(GEP);
+ GEP->getParent()->getInstList().erase(GEP);
+ }
+ }
+
+ // Increment I2 past all of the arguments added for this promoted pointer.
+ for (unsigned i = 0, e = ArgIndices.size(); i != e; ++i)
+ ++I2;
+ }
+
+ // Notify the alias analysis implementation that we inserted a new argument.
+ if (ExtraArgHack)
+ AA.copyValue(Constant::getNullValue(Type::Int32Ty), NF->arg_begin());
+
+
+ // Tell the alias analysis that the old function is about to disappear.
+ AA.replaceWithNewValue(F, NF);
+
+ // Now that the old function is dead, delete it.
+ F->getParent()->getFunctionList().erase(F);
+ return NF;
+}
diff --git a/lib/Transforms/IPO/ConstantMerge.cpp b/lib/Transforms/IPO/ConstantMerge.cpp
new file mode 100644
index 0000000..0c7ee59
--- /dev/null
+++ b/lib/Transforms/IPO/ConstantMerge.cpp
@@ -0,0 +1,116 @@
+//===- ConstantMerge.cpp - Merge duplicate global constants ---------------===//
+//
+// 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 defines the interface to a pass that merges duplicate global
+// constants together into a single constant that is shared. This is useful
+// because some passes (ie TraceValues) insert a lot of string constants into
+// the program, regardless of whether or not an existing string is available.
+//
+// Algorithm: ConstantMerge is designed to build up a map of available constants
+// and eliminate duplicates when it is initialized.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "constmerge"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Compiler.h"
+using namespace llvm;
+
+STATISTIC(NumMerged, "Number of global constants merged");
+
+namespace {
+ struct VISIBILITY_HIDDEN ConstantMerge : public ModulePass {
+ static char ID; // Pass identification, replacement for typeid
+ ConstantMerge() : ModulePass((intptr_t)&ID) {}
+
+ // run - For this pass, process all of the globals in the module,
+ // eliminating duplicate constants.
+ //
+ bool runOnModule(Module &M);
+ };
+
+ char ConstantMerge::ID = 0;
+ RegisterPass<ConstantMerge>X("constmerge","Merge Duplicate Global Constants");
+}
+
+ModulePass *llvm::createConstantMergePass() { return new ConstantMerge(); }
+
+bool ConstantMerge::runOnModule(Module &M) {
+ // Map unique constant/section pairs to globals. We don't want to merge
+ // globals in different sections.
+ std::map<std::pair<Constant*, std::string>, GlobalVariable*> CMap;
+
+ // Replacements - This vector contains a list of replacements to perform.
+ std::vector<std::pair<GlobalVariable*, GlobalVariable*> > Replacements;
+
+ bool MadeChange = false;
+
+ // Iterate constant merging while we are still making progress. Merging two
+ // constants together may allow us to merge other constants together if the
+ // second level constants have initializers which point to the globals that
+ // were just merged.
+ while (1) {
+ // First pass: identify all globals that can be merged together, filling in
+ // the Replacements vector. We cannot do the replacement in this pass
+ // because doing so may cause initializers of other globals to be rewritten,
+ // invalidating the Constant* pointers in CMap.
+ //
+ for (Module::global_iterator GVI = M.global_begin(), E = M.global_end();
+ GVI != E; ) {
+ GlobalVariable *GV = GVI++;
+
+ // If this GV is dead, remove it.
+ GV->removeDeadConstantUsers();
+ if (GV->use_empty() && GV->hasInternalLinkage()) {
+ GV->eraseFromParent();
+ continue;
+ }
+
+ // Only process constants with initializers.
+ if (GV->isConstant() && GV->hasInitializer()) {
+ Constant *Init = GV->getInitializer();
+
+ // Check to see if the initializer is already known.
+ GlobalVariable *&Slot = CMap[std::make_pair(Init, GV->getSection())];
+
+ if (Slot == 0) { // Nope, add it to the map.
+ Slot = GV;
+ } else if (GV->hasInternalLinkage()) { // Yup, this is a duplicate!
+ // Make all uses of the duplicate constant use the canonical version.
+ Replacements.push_back(std::make_pair(GV, Slot));
+ } else if (GV->hasInternalLinkage()) {
+ // Make all uses of the duplicate constant use the canonical version.
+ Replacements.push_back(std::make_pair(Slot, GV));
+ Slot = GV;
+ }
+ }
+ }
+
+ if (Replacements.empty())
+ return MadeChange;
+ CMap.clear();
+
+ // Now that we have figured out which replacements must be made, do them all
+ // now. This avoid invalidating the pointers in CMap, which are unneeded
+ // now.
+ for (unsigned i = 0, e = Replacements.size(); i != e; ++i) {
+ // Eliminate any uses of the dead global...
+ Replacements[i].first->replaceAllUsesWith(Replacements[i].second);
+
+ // Delete the global value from the module...
+ M.getGlobalList().erase(Replacements[i].first);
+ }
+
+ NumMerged += Replacements.size();
+ Replacements.clear();
+ }
+}
diff --git a/lib/Transforms/IPO/DeadArgumentElimination.cpp b/lib/Transforms/IPO/DeadArgumentElimination.cpp
new file mode 100644
index 0000000..943ea30
--- /dev/null
+++ b/lib/Transforms/IPO/DeadArgumentElimination.cpp
@@ -0,0 +1,703 @@
+//===-- DeadArgumentElimination.cpp - Eliminate dead arguments ------------===//
+//
+// 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 pass deletes dead arguments from internal functions. Dead argument
+// elimination removes arguments which are directly dead, as well as arguments
+// only passed into function calls as dead arguments of other functions. This
+// pass also deletes dead arguments in a similar way.
+//
+// This pass is often useful as a cleanup pass to run after aggressive
+// interprocedural passes, which add possibly-dead arguments.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "deadargelim"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/CallingConv.h"
+#include "llvm/Constant.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Compiler.h"
+#include <set>
+using namespace llvm;
+
+STATISTIC(NumArgumentsEliminated, "Number of unread args removed");
+STATISTIC(NumRetValsEliminated , "Number of unused return values removed");
+
+namespace {
+ /// DAE - The dead argument elimination pass.
+ ///
+ class VISIBILITY_HIDDEN DAE : public ModulePass {
+ /// Liveness enum - During our initial pass over the program, we determine
+ /// that things are either definately alive, definately dead, or in need of
+ /// interprocedural analysis (MaybeLive).
+ ///
+ enum Liveness { Live, MaybeLive, Dead };
+
+ /// LiveArguments, MaybeLiveArguments, DeadArguments - These sets contain
+ /// all of the arguments in the program. The Dead set contains arguments
+ /// which are completely dead (never used in the function). The MaybeLive
+ /// set contains arguments which are only passed into other function calls,
+ /// thus may be live and may be dead. The Live set contains arguments which
+ /// are known to be alive.
+ ///
+ std::set<Argument*> DeadArguments, MaybeLiveArguments, LiveArguments;
+
+ /// DeadRetVal, MaybeLiveRetVal, LifeRetVal - These sets contain all of the
+ /// functions in the program. The Dead set contains functions whose return
+ /// value is known to be dead. The MaybeLive set contains functions whose
+ /// return values are only used by return instructions, and the Live set
+ /// contains functions whose return values are used, functions that are
+ /// external, and functions that already return void.
+ ///
+ std::set<Function*> DeadRetVal, MaybeLiveRetVal, LiveRetVal;
+
+ /// InstructionsToInspect - As we mark arguments and return values
+ /// MaybeLive, we keep track of which instructions could make the values
+ /// live here. Once the entire program has had the return value and
+ /// arguments analyzed, this set is scanned to promote the MaybeLive objects
+ /// to be Live if they really are used.
+ std::vector<Instruction*> InstructionsToInspect;
+
+ /// CallSites - Keep track of the call sites of functions that have
+ /// MaybeLive arguments or return values.
+ std::multimap<Function*, CallSite> CallSites;
+
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ DAE() : ModulePass((intptr_t)&ID) {}
+ bool runOnModule(Module &M);
+
+ virtual bool ShouldHackArguments() const { return false; }
+
+ private:
+ Liveness getArgumentLiveness(const Argument &A);
+ bool isMaybeLiveArgumentNowLive(Argument *Arg);
+
+ bool DeleteDeadVarargs(Function &Fn);
+ void SurveyFunction(Function &Fn);
+
+ void MarkArgumentLive(Argument *Arg);
+ void MarkRetValLive(Function *F);
+ void MarkReturnInstArgumentLive(ReturnInst *RI);
+
+ void RemoveDeadArgumentsFromFunction(Function *F);
+ };
+ char DAE::ID = 0;
+ RegisterPass<DAE> X("deadargelim", "Dead Argument Elimination");
+
+ /// DAH - DeadArgumentHacking pass - Same as dead argument elimination, but
+ /// deletes arguments to functions which are external. This is only for use
+ /// by bugpoint.
+ struct DAH : public DAE {
+ static char ID;
+ virtual bool ShouldHackArguments() const { return true; }
+ };
+ char DAH::ID = 0;
+ RegisterPass<DAH> Y("deadarghaX0r",
+ "Dead Argument Hacking (BUGPOINT USE ONLY; DO NOT USE)");
+}
+
+/// createDeadArgEliminationPass - This pass removes arguments from functions
+/// which are not used by the body of the function.
+///
+ModulePass *llvm::createDeadArgEliminationPass() { return new DAE(); }
+ModulePass *llvm::createDeadArgHackingPass() { return new DAH(); }
+
+/// DeleteDeadVarargs - If this is an function that takes a ... list, and if
+/// llvm.vastart is never called, the varargs list is dead for the function.
+bool DAE::DeleteDeadVarargs(Function &Fn) {
+ assert(Fn.getFunctionType()->isVarArg() && "Function isn't varargs!");
+ if (Fn.isDeclaration() || !Fn.hasInternalLinkage()) return false;
+
+ // Ensure that the function is only directly called.
+ for (Value::use_iterator I = Fn.use_begin(), E = Fn.use_end(); I != E; ++I) {
+ // If this use is anything other than a call site, give up.
+ CallSite CS = CallSite::get(*I);
+ Instruction *TheCall = CS.getInstruction();
+ if (!TheCall) return false; // Not a direct call site?
+
+ // The addr of this function is passed to the call.
+ if (I.getOperandNo() != 0) return false;
+ }
+
+ // Okay, we know we can transform this function if safe. Scan its body
+ // looking for calls to llvm.vastart.
+ for (Function::iterator BB = Fn.begin(), E = Fn.end(); BB != E; ++BB) {
+ for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I) {
+ if (IntrinsicInst *II = dyn_cast<IntrinsicInst>(I)) {
+ if (II->getIntrinsicID() == Intrinsic::vastart)
+ return false;
+ }
+ }
+ }
+
+ // If we get here, there are no calls to llvm.vastart in the function body,
+ // remove the "..." and adjust all the calls.
+
+ // Start by computing a new prototype for the function, which is the same as
+ // the old function, but has fewer arguments.
+ const FunctionType *FTy = Fn.getFunctionType();
+ std::vector<const Type*> Params(FTy->param_begin(), FTy->param_end());
+ FunctionType *NFTy = FunctionType::get(FTy->getReturnType(), Params, false);
+ unsigned NumArgs = Params.size();
+
+ // Create the new function body and insert it into the module...
+ Function *NF = new Function(NFTy, Fn.getLinkage());
+ NF->setCallingConv(Fn.getCallingConv());
+ Fn.getParent()->getFunctionList().insert(&Fn, NF);
+ NF->takeName(&Fn);
+
+ // Loop over all of the callers of the function, transforming the call sites
+ // to pass in a smaller number of arguments into the new function.
+ //
+ std::vector<Value*> Args;
+ while (!Fn.use_empty()) {
+ CallSite CS = CallSite::get(Fn.use_back());
+ Instruction *Call = CS.getInstruction();
+
+ // Loop over the operands, dropping extraneous ones at the end of the list.
+ Args.assign(CS.arg_begin(), CS.arg_begin()+NumArgs);
+
+ Instruction *New;
+ if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
+ New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
+ &Args[0], Args.size(), "", Call);
+ cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
+ } else {
+ New = new CallInst(NF, &Args[0], Args.size(), "", Call);
+ cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
+ if (cast<CallInst>(Call)->isTailCall())
+ cast<CallInst>(New)->setTailCall();
+ }
+ Args.clear();
+
+ if (!Call->use_empty())
+ Call->replaceAllUsesWith(Constant::getNullValue(Call->getType()));
+
+ New->takeName(Call);
+
+ // Finally, remove the old call from the program, reducing the use-count of
+ // F.
+ Call->getParent()->getInstList().erase(Call);
+ }
+
+ // Since we have now created the new function, splice the body of the old
+ // function right into the new function, leaving the old rotting hulk of the
+ // function empty.
+ NF->getBasicBlockList().splice(NF->begin(), Fn.getBasicBlockList());
+
+ // Loop over the argument list, transfering uses of the old arguments over to
+ // the new arguments, also transfering over the names as well. While we're at
+ // it, remove the dead arguments from the DeadArguments list.
+ //
+ for (Function::arg_iterator I = Fn.arg_begin(), E = Fn.arg_end(),
+ I2 = NF->arg_begin(); I != E; ++I, ++I2) {
+ // Move the name and users over to the new version.
+ I->replaceAllUsesWith(I2);
+ I2->takeName(I);
+ }
+
+ // Finally, nuke the old function.
+ Fn.eraseFromParent();
+ return true;
+}
+
+
+static inline bool CallPassesValueThoughVararg(Instruction *Call,
+ const Value *Arg) {
+ CallSite CS = CallSite::get(Call);
+ const Type *CalledValueTy = CS.getCalledValue()->getType();
+ const Type *FTy = cast<PointerType>(CalledValueTy)->getElementType();
+ unsigned NumFixedArgs = cast<FunctionType>(FTy)->getNumParams();
+ for (CallSite::arg_iterator AI = CS.arg_begin()+NumFixedArgs;
+ AI != CS.arg_end(); ++AI)
+ if (AI->get() == Arg)
+ return true;
+ return false;
+}
+
+// getArgumentLiveness - Inspect an argument, determining if is known Live
+// (used in a computation), MaybeLive (only passed as an argument to a call), or
+// Dead (not used).
+DAE::Liveness DAE::getArgumentLiveness(const Argument &A) {
+ const FunctionType *FTy = A.getParent()->getFunctionType();
+
+ // If this is the return value of a struct function, it's not really dead.
+ if (FTy->isStructReturn() && &*A.getParent()->arg_begin() == &A)
+ return Live;
+
+ if (A.use_empty()) // First check, directly dead?
+ return Dead;
+
+ // Scan through all of the uses, looking for non-argument passing uses.
+ for (Value::use_const_iterator I = A.use_begin(), E = A.use_end(); I!=E;++I) {
+ // Return instructions do not immediately effect liveness.
+ if (isa<ReturnInst>(*I))
+ continue;
+
+ CallSite CS = CallSite::get(const_cast<User*>(*I));
+ if (!CS.getInstruction()) {
+ // If its used by something that is not a call or invoke, it's alive!
+ return Live;
+ }
+ // If it's an indirect call, mark it alive...
+ Function *Callee = CS.getCalledFunction();
+ if (!Callee) return Live;
+
+ // Check to see if it's passed through a va_arg area: if so, we cannot
+ // remove it.
+ if (CallPassesValueThoughVararg(CS.getInstruction(), &A))
+ return Live; // If passed through va_arg area, we cannot remove it
+ }
+
+ return MaybeLive; // It must be used, but only as argument to a function
+}
+
+
+// SurveyFunction - This performs the initial survey of the specified function,
+// checking out whether or not it uses any of its incoming arguments or whether
+// any callers use the return value. This fills in the
+// (Dead|MaybeLive|Live)(Arguments|RetVal) sets.
+//
+// We consider arguments of non-internal functions to be intrinsically alive as
+// well as arguments to functions which have their "address taken".
+//
+void DAE::SurveyFunction(Function &F) {
+ bool FunctionIntrinsicallyLive = false;
+ Liveness RetValLiveness = F.getReturnType() == Type::VoidTy ? Live : Dead;
+
+ if (!F.hasInternalLinkage() &&
+ (!ShouldHackArguments() || F.getIntrinsicID()))
+ FunctionIntrinsicallyLive = true;
+ else
+ for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I) {
+ // If this use is anything other than a call site, the function is alive.
+ CallSite CS = CallSite::get(*I);
+ Instruction *TheCall = CS.getInstruction();
+ if (!TheCall) { // Not a direct call site?
+ FunctionIntrinsicallyLive = true;
+ break;
+ }
+
+ // Check to see if the return value is used...
+ if (RetValLiveness != Live)
+ for (Value::use_iterator I = TheCall->use_begin(),
+ E = TheCall->use_end(); I != E; ++I)
+ if (isa<ReturnInst>(cast<Instruction>(*I))) {
+ RetValLiveness = MaybeLive;
+ } else if (isa<CallInst>(cast<Instruction>(*I)) ||
+ isa<InvokeInst>(cast<Instruction>(*I))) {
+ if (CallPassesValueThoughVararg(cast<Instruction>(*I), TheCall) ||
+ !CallSite::get(cast<Instruction>(*I)).getCalledFunction()) {
+ RetValLiveness = Live;
+ break;
+ } else {
+ RetValLiveness = MaybeLive;
+ }
+ } else {
+ RetValLiveness = Live;
+ break;
+ }
+
+ // If the function is PASSED IN as an argument, its address has been taken
+ for (CallSite::arg_iterator AI = CS.arg_begin(), E = CS.arg_end();
+ AI != E; ++AI)
+ if (AI->get() == &F) {
+ FunctionIntrinsicallyLive = true;
+ break;
+ }
+ if (FunctionIntrinsicallyLive) break;
+ }
+
+ if (FunctionIntrinsicallyLive) {
+ DOUT << " Intrinsically live fn: " << F.getName() << "\n";
+ for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
+ AI != E; ++AI)
+ LiveArguments.insert(AI);
+ LiveRetVal.insert(&F);
+ return;
+ }
+
+ switch (RetValLiveness) {
+ case Live: LiveRetVal.insert(&F); break;
+ case MaybeLive: MaybeLiveRetVal.insert(&F); break;
+ case Dead: DeadRetVal.insert(&F); break;
+ }
+
+ DOUT << " Inspecting args for fn: " << F.getName() << "\n";
+
+ // If it is not intrinsically alive, we know that all users of the
+ // function are call sites. Mark all of the arguments live which are
+ // directly used, and keep track of all of the call sites of this function
+ // if there are any arguments we assume that are dead.
+ //
+ bool AnyMaybeLiveArgs = false;
+ for (Function::arg_iterator AI = F.arg_begin(), E = F.arg_end();
+ AI != E; ++AI)
+ switch (getArgumentLiveness(*AI)) {
+ case Live:
+ DOUT << " Arg live by use: " << AI->getName() << "\n";
+ LiveArguments.insert(AI);
+ break;
+ case Dead:
+ DOUT << " Arg definitely dead: " << AI->getName() <<"\n";
+ DeadArguments.insert(AI);
+ break;
+ case MaybeLive:
+ DOUT << " Arg only passed to calls: " << AI->getName() << "\n";
+ AnyMaybeLiveArgs = true;
+ MaybeLiveArguments.insert(AI);
+ break;
+ }
+
+ // If there are any "MaybeLive" arguments, we need to check callees of
+ // this function when/if they become alive. Record which functions are
+ // callees...
+ if (AnyMaybeLiveArgs || RetValLiveness == MaybeLive)
+ for (Value::use_iterator I = F.use_begin(), E = F.use_end();
+ I != E; ++I) {
+ if (AnyMaybeLiveArgs)
+ CallSites.insert(std::make_pair(&F, CallSite::get(*I)));
+
+ if (RetValLiveness == MaybeLive)
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
+ UI != E; ++UI)
+ InstructionsToInspect.push_back(cast<Instruction>(*UI));
+ }
+}
+
+// isMaybeLiveArgumentNowLive - Check to see if Arg is alive. At this point, we
+// know that the only uses of Arg are to be passed in as an argument to a
+// function call or return. Check to see if the formal argument passed in is in
+// the LiveArguments set. If so, return true.
+//
+bool DAE::isMaybeLiveArgumentNowLive(Argument *Arg) {
+ for (Value::use_iterator I = Arg->use_begin(), E = Arg->use_end(); I!=E; ++I){
+ if (isa<ReturnInst>(*I)) {
+ if (LiveRetVal.count(Arg->getParent())) return true;
+ continue;
+ }
+
+ CallSite CS = CallSite::get(*I);
+
+ // We know that this can only be used for direct calls...
+ Function *Callee = CS.getCalledFunction();
+
+ // Loop over all of the arguments (because Arg may be passed into the call
+ // multiple times) and check to see if any are now alive...
+ CallSite::arg_iterator CSAI = CS.arg_begin();
+ for (Function::arg_iterator AI = Callee->arg_begin(), E = Callee->arg_end();
+ AI != E; ++AI, ++CSAI)
+ // If this is the argument we are looking for, check to see if it's alive
+ if (*CSAI == Arg && LiveArguments.count(AI))
+ return true;
+ }
+ return false;
+}
+
+/// MarkArgumentLive - The MaybeLive argument 'Arg' is now known to be alive.
+/// Mark it live in the specified sets and recursively mark arguments in callers
+/// live that are needed to pass in a value.
+///
+void DAE::MarkArgumentLive(Argument *Arg) {
+ std::set<Argument*>::iterator It = MaybeLiveArguments.lower_bound(Arg);
+ if (It == MaybeLiveArguments.end() || *It != Arg) return;
+
+ DOUT << " MaybeLive argument now live: " << Arg->getName() <<"\n";
+ MaybeLiveArguments.erase(It);
+ LiveArguments.insert(Arg);
+
+ // Loop over all of the call sites of the function, making any arguments
+ // passed in to provide a value for this argument live as necessary.
+ //
+ Function *Fn = Arg->getParent();
+ unsigned ArgNo = std::distance(Fn->arg_begin(), Function::arg_iterator(Arg));
+
+ std::multimap<Function*, CallSite>::iterator I = CallSites.lower_bound(Fn);
+ for (; I != CallSites.end() && I->first == Fn; ++I) {
+ CallSite CS = I->second;
+ Value *ArgVal = *(CS.arg_begin()+ArgNo);
+ if (Argument *ActualArg = dyn_cast<Argument>(ArgVal)) {
+ MarkArgumentLive(ActualArg);
+ } else {
+ // If the value passed in at this call site is a return value computed by
+ // some other call site, make sure to mark the return value at the other
+ // call site as being needed.
+ CallSite ArgCS = CallSite::get(ArgVal);
+ if (ArgCS.getInstruction())
+ if (Function *Fn = ArgCS.getCalledFunction())
+ MarkRetValLive(Fn);
+ }
+ }
+}
+
+/// MarkArgumentLive - The MaybeLive return value for the specified function is
+/// now known to be alive. Propagate this fact to the return instructions which
+/// produce it.
+void DAE::MarkRetValLive(Function *F) {
+ assert(F && "Shame shame, we can't have null pointers here!");
+
+ // Check to see if we already knew it was live
+ std::set<Function*>::iterator I = MaybeLiveRetVal.lower_bound(F);
+ if (I == MaybeLiveRetVal.end() || *I != F) return; // It's already alive!
+
+ DOUT << " MaybeLive retval now live: " << F->getName() << "\n";
+
+ MaybeLiveRetVal.erase(I);
+ LiveRetVal.insert(F); // It is now known to be live!
+
+ // Loop over all of the functions, noticing that the return value is now live.
+ for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+ if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()))
+ MarkReturnInstArgumentLive(RI);
+}
+
+void DAE::MarkReturnInstArgumentLive(ReturnInst *RI) {
+ Value *Op = RI->getOperand(0);
+ if (Argument *A = dyn_cast<Argument>(Op)) {
+ MarkArgumentLive(A);
+ } else if (CallInst *CI = dyn_cast<CallInst>(Op)) {
+ if (Function *F = CI->getCalledFunction())
+ MarkRetValLive(F);
+ } else if (InvokeInst *II = dyn_cast<InvokeInst>(Op)) {
+ if (Function *F = II->getCalledFunction())
+ MarkRetValLive(F);
+ }
+}
+
+// RemoveDeadArgumentsFromFunction - We know that F has dead arguments, as
+// specified by the DeadArguments list. Transform the function and all of the
+// callees of the function to not have these arguments.
+//
+void DAE::RemoveDeadArgumentsFromFunction(Function *F) {
+ // Start by computing a new prototype for the function, which is the same as
+ // the old function, but has fewer arguments.
+ const FunctionType *FTy = F->getFunctionType();
+ std::vector<const Type*> Params;
+
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+ if (!DeadArguments.count(I))
+ Params.push_back(I->getType());
+
+ const Type *RetTy = FTy->getReturnType();
+ if (DeadRetVal.count(F)) {
+ RetTy = Type::VoidTy;
+ DeadRetVal.erase(F);
+ }
+
+ // Work around LLVM bug PR56: the CWriter cannot emit varargs functions which
+ // have zero fixed arguments.
+ //
+ bool ExtraArgHack = false;
+ if (Params.empty() && FTy->isVarArg()) {
+ ExtraArgHack = true;
+ Params.push_back(Type::Int32Ty);
+ }
+
+ FunctionType *NFTy = FunctionType::get(RetTy, Params, FTy->isVarArg());
+
+ // Create the new function body and insert it into the module...
+ Function *NF = new Function(NFTy, F->getLinkage());
+ NF->setCallingConv(F->getCallingConv());
+ F->getParent()->getFunctionList().insert(F, NF);
+ NF->takeName(F);
+
+ // Loop over all of the callers of the function, transforming the call sites
+ // to pass in a smaller number of arguments into the new function.
+ //
+ std::vector<Value*> Args;
+ while (!F->use_empty()) {
+ CallSite CS = CallSite::get(F->use_back());
+ Instruction *Call = CS.getInstruction();
+
+ // Loop over the operands, deleting dead ones...
+ CallSite::arg_iterator AI = CS.arg_begin();
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end();
+ I != E; ++I, ++AI)
+ if (!DeadArguments.count(I)) // Remove operands for dead arguments
+ Args.push_back(*AI);
+
+ if (ExtraArgHack)
+ Args.push_back(UndefValue::get(Type::Int32Ty));
+
+ // Push any varargs arguments on the list
+ for (; AI != CS.arg_end(); ++AI)
+ Args.push_back(*AI);
+
+ Instruction *New;
+ if (InvokeInst *II = dyn_cast<InvokeInst>(Call)) {
+ New = new InvokeInst(NF, II->getNormalDest(), II->getUnwindDest(),
+ &Args[0], Args.size(), "", Call);
+ cast<InvokeInst>(New)->setCallingConv(CS.getCallingConv());
+ } else {
+ New = new CallInst(NF, &Args[0], Args.size(), "", Call);
+ cast<CallInst>(New)->setCallingConv(CS.getCallingConv());
+ if (cast<CallInst>(Call)->isTailCall())
+ cast<CallInst>(New)->setTailCall();
+ }
+ Args.clear();
+
+ if (!Call->use_empty()) {
+ if (New->getType() == Type::VoidTy)
+ Call->replaceAllUsesWith(Constant::getNullValue(Call->getType()));
+ else {
+ Call->replaceAllUsesWith(New);
+ New->takeName(Call);
+ }
+ }
+
+ // Finally, remove the old call from the program, reducing the use-count of
+ // F.
+ Call->getParent()->getInstList().erase(Call);
+ }
+
+ // Since we have now created the new function, splice the body of the old
+ // function right into the new function, leaving the old rotting hulk of the
+ // function empty.
+ NF->getBasicBlockList().splice(NF->begin(), F->getBasicBlockList());
+
+ // Loop over the argument list, transfering uses of the old arguments over to
+ // the new arguments, also transfering over the names as well. While we're at
+ // it, remove the dead arguments from the DeadArguments list.
+ //
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(),
+ I2 = NF->arg_begin();
+ I != E; ++I)
+ if (!DeadArguments.count(I)) {
+ // If this is a live argument, move the name and users over to the new
+ // version.
+ I->replaceAllUsesWith(I2);
+ I2->takeName(I);
+ ++I2;
+ } else {
+ // If this argument is dead, replace any uses of it with null constants
+ // (these are guaranteed to only be operands to call instructions which
+ // will later be simplified).
+ I->replaceAllUsesWith(Constant::getNullValue(I->getType()));
+ DeadArguments.erase(I);
+ }
+
+ // If we change the return value of the function we must rewrite any return
+ // instructions. Check this now.
+ if (F->getReturnType() != NF->getReturnType())
+ for (Function::iterator BB = NF->begin(), E = NF->end(); BB != E; ++BB)
+ if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
+ new ReturnInst(0, RI);
+ BB->getInstList().erase(RI);
+ }
+
+ // Now that the old function is dead, delete it.
+ F->getParent()->getFunctionList().erase(F);
+}
+
+bool DAE::runOnModule(Module &M) {
+ // First phase: loop through the module, determining which arguments are live.
+ // We assume all arguments are dead unless proven otherwise (allowing us to
+ // determine that dead arguments passed into recursive functions are dead).
+ //
+ DOUT << "DAE - Determining liveness\n";
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ) {
+ Function &F = *I++;
+ if (F.getFunctionType()->isVarArg())
+ if (DeleteDeadVarargs(F))
+ continue;
+
+ SurveyFunction(F);
+ }
+
+ // Loop over the instructions to inspect, propagating liveness among arguments
+ // and return values which are MaybeLive.
+
+ while (!InstructionsToInspect.empty()) {
+ Instruction *I = InstructionsToInspect.back();
+ InstructionsToInspect.pop_back();
+
+ if (ReturnInst *RI = dyn_cast<ReturnInst>(I)) {
+ // For return instructions, we just have to check to see if the return
+ // value for the current function is known now to be alive. If so, any
+ // arguments used by it are now alive, and any call instruction return
+ // value is alive as well.
+ if (LiveRetVal.count(RI->getParent()->getParent()))
+ MarkReturnInstArgumentLive(RI);
+
+ } else {
+ CallSite CS = CallSite::get(I);
+ assert(CS.getInstruction() && "Unknown instruction for the I2I list!");
+
+ Function *Callee = CS.getCalledFunction();
+
+ // If we found a call or invoke instruction on this list, that means that
+ // an argument of the function is a call instruction. If the argument is
+ // live, then the return value of the called instruction is now live.
+ //
+ CallSite::arg_iterator AI = CS.arg_begin(); // ActualIterator
+ for (Function::arg_iterator FI = Callee->arg_begin(),
+ E = Callee->arg_end(); FI != E; ++AI, ++FI) {
+ // If this argument is another call...
+ CallSite ArgCS = CallSite::get(*AI);
+ if (ArgCS.getInstruction() && LiveArguments.count(FI))
+ if (Function *Callee = ArgCS.getCalledFunction())
+ MarkRetValLive(Callee);
+ }
+ }
+ }
+
+ // Now we loop over all of the MaybeLive arguments, promoting them to be live
+ // arguments if one of the calls that uses the arguments to the calls they are
+ // passed into requires them to be live. Of course this could make other
+ // arguments live, so process callers recursively.
+ //
+ // Because elements can be removed from the MaybeLiveArguments set, copy it to
+ // a temporary vector.
+ //
+ std::vector<Argument*> TmpArgList(MaybeLiveArguments.begin(),
+ MaybeLiveArguments.end());
+ for (unsigned i = 0, e = TmpArgList.size(); i != e; ++i) {
+ Argument *MLA = TmpArgList[i];
+ if (MaybeLiveArguments.count(MLA) &&
+ isMaybeLiveArgumentNowLive(MLA))
+ MarkArgumentLive(MLA);
+ }
+
+ // Recover memory early...
+ CallSites.clear();
+
+ // At this point, we know that all arguments in DeadArguments and
+ // MaybeLiveArguments are dead. If the two sets are empty, there is nothing
+ // to do.
+ if (MaybeLiveArguments.empty() && DeadArguments.empty() &&
+ MaybeLiveRetVal.empty() && DeadRetVal.empty())
+ return false;
+
+ // Otherwise, compact into one set, and start eliminating the arguments from
+ // the functions.
+ DeadArguments.insert(MaybeLiveArguments.begin(), MaybeLiveArguments.end());
+ MaybeLiveArguments.clear();
+ DeadRetVal.insert(MaybeLiveRetVal.begin(), MaybeLiveRetVal.end());
+ MaybeLiveRetVal.clear();
+
+ LiveArguments.clear();
+ LiveRetVal.clear();
+
+ NumArgumentsEliminated += DeadArguments.size();
+ NumRetValsEliminated += DeadRetVal.size();
+ while (!DeadArguments.empty())
+ RemoveDeadArgumentsFromFunction((*DeadArguments.begin())->getParent());
+
+ while (!DeadRetVal.empty())
+ RemoveDeadArgumentsFromFunction(*DeadRetVal.begin());
+ return true;
+}
diff --git a/lib/Transforms/IPO/DeadTypeElimination.cpp b/lib/Transforms/IPO/DeadTypeElimination.cpp
new file mode 100644
index 0000000..87b725a
--- /dev/null
+++ b/lib/Transforms/IPO/DeadTypeElimination.cpp
@@ -0,0 +1,106 @@
+//===- DeadTypeElimination.cpp - Eliminate unused types for symbol table --===//
+//
+// 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 pass is used to cleanup the output of GCC. It eliminate names for types
+// that are unused in the entire translation unit, using the FindUsedTypes pass.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "deadtypeelim"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Analysis/FindUsedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/TypeSymbolTable.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Compiler.h"
+using namespace llvm;
+
+STATISTIC(NumKilled, "Number of unused typenames removed from symtab");
+
+namespace {
+ struct VISIBILITY_HIDDEN DTE : public ModulePass {
+ static char ID; // Pass identification, replacement for typeid
+ DTE() : ModulePass((intptr_t)&ID) {}
+
+ // doPassInitialization - For this pass, it removes global symbol table
+ // entries for primitive types. These are never used for linking in GCC and
+ // they make the output uglier to look at, so we nuke them.
+ //
+ // Also, initialize instance variables.
+ //
+ bool runOnModule(Module &M);
+
+ // getAnalysisUsage - This function needs FindUsedTypes to do its job...
+ //
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<FindUsedTypes>();
+ }
+ };
+ char DTE::ID = 0;
+ RegisterPass<DTE> X("deadtypeelim", "Dead Type Elimination");
+}
+
+ModulePass *llvm::createDeadTypeEliminationPass() {
+ return new DTE();
+}
+
+
+// ShouldNukeSymtabEntry - Return true if this module level symbol table entry
+// should be eliminated.
+//
+static inline bool ShouldNukeSymtabEntry(const Type *Ty){
+ // Nuke all names for primitive types!
+ if (Ty->isPrimitiveType() || Ty->isInteger())
+ return true;
+
+ // Nuke all pointers to primitive types as well...
+ if (const PointerType *PT = dyn_cast<PointerType>(Ty))
+ if (PT->getElementType()->isPrimitiveType() ||
+ PT->getElementType()->isInteger())
+ return true;
+
+ return false;
+}
+
+// run - For this pass, it removes global symbol table entries for primitive
+// types. These are never used for linking in GCC and they make the output
+// uglier to look at, so we nuke them. Also eliminate types that are never used
+// in the entire program as indicated by FindUsedTypes.
+//
+bool DTE::runOnModule(Module &M) {
+ bool Changed = false;
+
+ TypeSymbolTable &ST = M.getTypeSymbolTable();
+ std::set<const Type *> UsedTypes = getAnalysis<FindUsedTypes>().getTypes();
+
+ // Check the symbol table for superfluous type entries...
+ //
+ // Grab the 'type' plane of the module symbol...
+ TypeSymbolTable::iterator TI = ST.begin();
+ TypeSymbolTable::iterator TE = ST.end();
+ while ( TI != TE ) {
+ // If this entry should be unconditionally removed, or if we detect that
+ // the type is not used, remove it.
+ const Type *RHS = TI->second;
+ if (ShouldNukeSymtabEntry(RHS) || !UsedTypes.count(RHS)) {
+ ST.remove(TI++);
+ ++NumKilled;
+ Changed = true;
+ } else {
+ ++TI;
+ // We only need to leave one name for each type.
+ UsedTypes.erase(RHS);
+ }
+ }
+
+ return Changed;
+}
+
+// vim: sw=2
diff --git a/lib/Transforms/IPO/ExtractFunction.cpp b/lib/Transforms/IPO/ExtractFunction.cpp
new file mode 100644
index 0000000..8d6af41
--- /dev/null
+++ b/lib/Transforms/IPO/ExtractFunction.cpp
@@ -0,0 +1,144 @@
+//===-- ExtractFunction.cpp - Function extraction pass --------------------===//
+//
+// 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 pass extracts
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Support/Compiler.h"
+using namespace llvm;
+
+namespace {
+ /// @brief A pass to extract specific functions and their dependencies.
+ class VISIBILITY_HIDDEN FunctionExtractorPass : public ModulePass {
+ Function *Named;
+ bool deleteFunc;
+ bool reLink;
+ public:
+ static char ID; // Pass identification, replacement for typeid
+
+ /// FunctionExtractorPass - If deleteFn is true, this pass deletes as the
+ /// specified function. Otherwise, it deletes as much of the module as
+ /// possible, except for the function specified.
+ ///
+ FunctionExtractorPass(Function *F = 0, bool deleteFn = true,
+ bool relinkCallees = false)
+ : ModulePass((intptr_t)&ID), Named(F), deleteFunc(deleteFn),
+ reLink(relinkCallees) {}
+
+ bool runOnModule(Module &M) {
+ if (Named == 0) {
+ Named = M.getFunction("main");
+ if (Named == 0) return false; // No function to extract
+ }
+
+ if (deleteFunc)
+ return deleteFunction();
+ M.setModuleInlineAsm("");
+ return isolateFunction(M);
+ }
+
+ bool deleteFunction() {
+ // If we're in relinking mode, set linkage of all internal callees to
+ // external. This will allow us extract function, and then - link
+ // everything together
+ if (reLink) {
+ for (Function::iterator B = Named->begin(), BE = Named->end();
+ B != BE; ++B) {
+ for (BasicBlock::iterator I = B->begin(), E = B->end();
+ I != E; ++I) {
+ if (CallInst* callInst = dyn_cast<CallInst>(&*I)) {
+ Function* Callee = callInst->getCalledFunction();
+ if (Callee && Callee->hasInternalLinkage())
+ Callee->setLinkage(GlobalValue::ExternalLinkage);
+ }
+ }
+ }
+ }
+
+ Named->setLinkage(GlobalValue::ExternalLinkage);
+ Named->deleteBody();
+ assert(Named->isDeclaration() && "This didn't make the function external!");
+ return true;
+ }
+
+ bool isolateFunction(Module &M) {
+ // Make sure our result is globally accessible...
+ Named->setLinkage(GlobalValue::ExternalLinkage);
+
+ // Mark all global variables internal
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
+ if (!I->isDeclaration()) {
+ I->setInitializer(0); // Make all variables external
+ I->setLinkage(GlobalValue::ExternalLinkage);
+ }
+
+ // All of the functions may be used by global variables or the named
+ // function. Loop through them and create a new, external functions that
+ // can be "used", instead of ones with bodies.
+ std::vector<Function*> NewFunctions;
+
+ Function *Last = --M.end(); // Figure out where the last real fn is.
+
+ for (Module::iterator I = M.begin(); ; ++I) {
+ if (&*I != Named) {
+ Function *New = new Function(I->getFunctionType(),
+ GlobalValue::ExternalLinkage);
+ New->setCallingConv(I->getCallingConv());
+
+ // If it's not the named function, delete the body of the function
+ I->dropAllReferences();
+
+ M.getFunctionList().push_back(New);
+ NewFunctions.push_back(New);
+ New->takeName(I);
+ }
+
+ if (&*I == Last) break; // Stop after processing the last function
+ }
+
+ // Now that we have replacements all set up, loop through the module,
+ // deleting the old functions, replacing them with the newly created
+ // functions.
+ if (!NewFunctions.empty()) {
+ unsigned FuncNum = 0;
+ Module::iterator I = M.begin();
+ do {
+ if (&*I != Named) {
+ // Make everything that uses the old function use the new dummy fn
+ I->replaceAllUsesWith(NewFunctions[FuncNum++]);
+
+ Function *Old = I;
+ ++I; // Move the iterator to the new function
+
+ // Delete the old function!
+ M.getFunctionList().erase(Old);
+
+ } else {
+ ++I; // Skip the function we are extracting
+ }
+ } while (&*I != NewFunctions[0]);
+ }
+
+ return true;
+ }
+ };
+
+ char FunctionExtractorPass::ID = 0;
+ RegisterPass<FunctionExtractorPass> X("extract", "Function Extractor");
+}
+
+ModulePass *llvm::createFunctionExtractionPass(Function *F, bool deleteFn,
+ bool relinkCallees) {
+ return new FunctionExtractorPass(F, deleteFn, relinkCallees);
+}
diff --git a/lib/Transforms/IPO/GlobalDCE.cpp b/lib/Transforms/IPO/GlobalDCE.cpp
new file mode 100644
index 0000000..09cfa21
--- /dev/null
+++ b/lib/Transforms/IPO/GlobalDCE.cpp
@@ -0,0 +1,203 @@
+//===-- GlobalDCE.cpp - DCE unreachable internal functions ----------------===//
+//
+// 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 transform is designed to eliminate unreachable internal globals from the
+// program. It uses an aggressive algorithm, searching out globals that are
+// known to be alive. After it finds all of the globals which are needed, it
+// deletes whatever is left over. This allows it to delete recursive chunks of
+// the program which are unreachable.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "globaldce"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Constants.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Compiler.h"
+#include <set>
+using namespace llvm;
+
+STATISTIC(NumFunctions, "Number of functions removed");
+STATISTIC(NumVariables, "Number of global variables removed");
+
+namespace {
+ struct VISIBILITY_HIDDEN GlobalDCE : public ModulePass {
+ static char ID; // Pass identification, replacement for typeid
+ GlobalDCE() : ModulePass((intptr_t)&ID) {}
+
+ // run - Do the GlobalDCE pass on the specified module, optionally updating
+ // the specified callgraph to reflect the changes.
+ //
+ bool runOnModule(Module &M);
+
+ private:
+ std::set<GlobalValue*> AliveGlobals;
+
+ /// MarkGlobalIsNeeded - the specific global value as needed, and
+ /// recursively mark anything that it uses as also needed.
+ void GlobalIsNeeded(GlobalValue *GV);
+ void MarkUsedGlobalsAsNeeded(Constant *C);
+
+ bool SafeToDestroyConstant(Constant* C);
+ bool RemoveUnusedGlobalValue(GlobalValue &GV);
+ };
+ char GlobalDCE::ID = 0;
+ RegisterPass<GlobalDCE> X("globaldce", "Dead Global Elimination");
+}
+
+ModulePass *llvm::createGlobalDCEPass() { return new GlobalDCE(); }
+
+bool GlobalDCE::runOnModule(Module &M) {
+ bool Changed = false;
+ // Loop over the module, adding globals which are obviously necessary.
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
+ Changed |= RemoveUnusedGlobalValue(*I);
+ // Functions with external linkage are needed if they have a body
+ if ((!I->hasInternalLinkage() && !I->hasLinkOnceLinkage()) &&
+ !I->isDeclaration())
+ GlobalIsNeeded(I);
+ }
+
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I) {
+ Changed |= RemoveUnusedGlobalValue(*I);
+ // Externally visible & appending globals are needed, if they have an
+ // initializer.
+ if ((!I->hasInternalLinkage() && !I->hasLinkOnceLinkage()) &&
+ !I->isDeclaration())
+ GlobalIsNeeded(I);
+ }
+
+
+ for (Module::alias_iterator I = M.alias_begin(), E = M.alias_end();
+ I != E; ++I) {
+ // Aliases are always needed even if they are not used.
+ MarkUsedGlobalsAsNeeded(I->getAliasee());
+ }
+
+ // Now that all globals which are needed are in the AliveGlobals set, we loop
+ // through the program, deleting those which are not alive.
+ //
+
+ // The first pass is to drop initializers of global variables which are dead.
+ std::vector<GlobalVariable*> DeadGlobalVars; // Keep track of dead globals
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end(); I != E; ++I)
+ if (!AliveGlobals.count(I)) {
+ DeadGlobalVars.push_back(I); // Keep track of dead globals
+ I->setInitializer(0);
+ }
+
+
+ // The second pass drops the bodies of functions which are dead...
+ std::vector<Function*> DeadFunctions;
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (!AliveGlobals.count(I)) {
+ DeadFunctions.push_back(I); // Keep track of dead globals
+ if (!I->isDeclaration())
+ I->deleteBody();
+ }
+
+ if (!DeadFunctions.empty()) {
+ // Now that all interreferences have been dropped, delete the actual objects
+ // themselves.
+ for (unsigned i = 0, e = DeadFunctions.size(); i != e; ++i) {
+ RemoveUnusedGlobalValue(*DeadFunctions[i]);
+ M.getFunctionList().erase(DeadFunctions[i]);
+ }
+ NumFunctions += DeadFunctions.size();
+ Changed = true;
+ }
+
+ if (!DeadGlobalVars.empty()) {
+ for (unsigned i = 0, e = DeadGlobalVars.size(); i != e; ++i) {
+ RemoveUnusedGlobalValue(*DeadGlobalVars[i]);
+ M.getGlobalList().erase(DeadGlobalVars[i]);
+ }
+ NumVariables += DeadGlobalVars.size();
+ Changed = true;
+ }
+
+ // Make sure that all memory is released
+ AliveGlobals.clear();
+ return Changed;
+}
+
+/// MarkGlobalIsNeeded - the specific global value as needed, and
+/// recursively mark anything that it uses as also needed.
+void GlobalDCE::GlobalIsNeeded(GlobalValue *G) {
+ std::set<GlobalValue*>::iterator I = AliveGlobals.lower_bound(G);
+
+ // If the global is already in the set, no need to reprocess it.
+ if (I != AliveGlobals.end() && *I == G) return;
+
+ // Otherwise insert it now, so we do not infinitely recurse
+ AliveGlobals.insert(I, G);
+
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(G)) {
+ // If this is a global variable, we must make sure to add any global values
+ // referenced by the initializer to the alive set.
+ if (GV->hasInitializer())
+ MarkUsedGlobalsAsNeeded(GV->getInitializer());
+ } else if (!isa<GlobalAlias>(G)) {
+ // Otherwise this must be a function object. We have to scan the body of
+ // the function looking for constants and global values which are used as
+ // operands. Any operands of these types must be processed to ensure that
+ // any globals used will be marked as needed.
+ Function *F = cast<Function>(G);
+ // For all basic blocks...
+ for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+ // For all instructions...
+ for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
+ // For all operands...
+ for (User::op_iterator U = I->op_begin(), E = I->op_end(); U != E; ++U)
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(*U))
+ GlobalIsNeeded(GV);
+ else if (Constant *C = dyn_cast<Constant>(*U))
+ MarkUsedGlobalsAsNeeded(C);
+ }
+}
+
+void GlobalDCE::MarkUsedGlobalsAsNeeded(Constant *C) {
+ if (GlobalValue *GV = dyn_cast<GlobalValue>(C))
+ GlobalIsNeeded(GV);
+ else {
+ // Loop over all of the operands of the constant, adding any globals they
+ // use to the list of needed globals.
+ for (User::op_iterator I = C->op_begin(), E = C->op_end(); I != E; ++I)
+ MarkUsedGlobalsAsNeeded(cast<Constant>(*I));
+ }
+}
+
+// RemoveUnusedGlobalValue - Loop over all of the uses of the specified
+// GlobalValue, looking for the constant pointer ref that may be pointing to it.
+// If found, check to see if the constant pointer ref is safe to destroy, and if
+// so, nuke it. This will reduce the reference count on the global value, which
+// might make it deader.
+//
+bool GlobalDCE::RemoveUnusedGlobalValue(GlobalValue &GV) {
+ if (GV.use_empty()) return false;
+ GV.removeDeadConstantUsers();
+ return GV.use_empty();
+}
+
+// SafeToDestroyConstant - It is safe to destroy a constant iff it is only used
+// by constants itself. Note that constants cannot be cyclic, so this test is
+// pretty easy to implement recursively.
+//
+bool GlobalDCE::SafeToDestroyConstant(Constant *C) {
+ for (Value::use_iterator I = C->use_begin(), E = C->use_end(); I != E; ++I)
+ if (Constant *User = dyn_cast<Constant>(*I)) {
+ if (!SafeToDestroyConstant(User)) return false;
+ } else {
+ return false;
+ }
+ return true;
+}
diff --git a/lib/Transforms/IPO/GlobalOpt.cpp b/lib/Transforms/IPO/GlobalOpt.cpp
new file mode 100644
index 0000000..520af87
--- /dev/null
+++ b/lib/Transforms/IPO/GlobalOpt.cpp
@@ -0,0 +1,1988 @@
+//===- GlobalOpt.cpp - Optimize Global Variables --------------------------===//
+//
+// 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 pass transforms simple global variables that never have their address
+// taken. If obviously true, it marks read/write globals as constant, deletes
+// variables only stored to, etc.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "globalopt"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/CallingConv.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Analysis/ConstantFolding.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include <algorithm>
+#include <set>
+using namespace llvm;
+
+STATISTIC(NumMarked , "Number of globals marked constant");
+STATISTIC(NumSRA , "Number of aggregate globals broken into scalars");
+STATISTIC(NumHeapSRA , "Number of heap objects SRA'd");
+STATISTIC(NumSubstitute,"Number of globals with initializers stored into them");
+STATISTIC(NumDeleted , "Number of globals deleted");
+STATISTIC(NumFnDeleted , "Number of functions deleted");
+STATISTIC(NumGlobUses , "Number of global uses devirtualized");
+STATISTIC(NumLocalized , "Number of globals localized");
+STATISTIC(NumShrunkToBool , "Number of global vars shrunk to booleans");
+STATISTIC(NumFastCallFns , "Number of functions converted to fastcc");
+STATISTIC(NumCtorsEvaluated, "Number of static ctors evaluated");
+
+namespace {
+ struct VISIBILITY_HIDDEN GlobalOpt : public ModulePass {
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequired<TargetData>();
+ }
+ static char ID; // Pass identification, replacement for typeid
+ GlobalOpt() : ModulePass((intptr_t)&ID) {}
+
+ bool runOnModule(Module &M);
+
+ private:
+ GlobalVariable *FindGlobalCtors(Module &M);
+ bool OptimizeFunctions(Module &M);
+ bool OptimizeGlobalVars(Module &M);
+ bool OptimizeGlobalCtorsList(GlobalVariable *&GCL);
+ bool ProcessInternalGlobal(GlobalVariable *GV,Module::global_iterator &GVI);
+ };
+
+ char GlobalOpt::ID = 0;
+ RegisterPass<GlobalOpt> X("globalopt", "Global Variable Optimizer");
+}
+
+ModulePass *llvm::createGlobalOptimizerPass() { return new GlobalOpt(); }
+
+/// GlobalStatus - As we analyze each global, keep track of some information
+/// about it. If we find out that the address of the global is taken, none of
+/// this info will be accurate.
+struct VISIBILITY_HIDDEN GlobalStatus {
+ /// isLoaded - True if the global is ever loaded. If the global isn't ever
+ /// loaded it can be deleted.
+ bool isLoaded;
+
+ /// StoredType - Keep track of what stores to the global look like.
+ ///
+ enum StoredType {
+ /// NotStored - There is no store to this global. It can thus be marked
+ /// constant.
+ NotStored,
+
+ /// isInitializerStored - This global is stored to, but the only thing
+ /// stored is the constant it was initialized with. This is only tracked
+ /// for scalar globals.
+ isInitializerStored,
+
+ /// isStoredOnce - This global is stored to, but only its initializer and
+ /// one other value is ever stored to it. If this global isStoredOnce, we
+ /// track the value stored to it in StoredOnceValue below. This is only
+ /// tracked for scalar globals.
+ isStoredOnce,
+
+ /// isStored - This global is stored to by multiple values or something else
+ /// that we cannot track.
+ isStored
+ } StoredType;
+
+ /// StoredOnceValue - If only one value (besides the initializer constant) is
+ /// ever stored to this global, keep track of what value it is.
+ Value *StoredOnceValue;
+
+ /// AccessingFunction/HasMultipleAccessingFunctions - These start out
+ /// null/false. When the first accessing function is noticed, it is recorded.
+ /// When a second different accessing function is noticed,
+ /// HasMultipleAccessingFunctions is set to true.
+ Function *AccessingFunction;
+ bool HasMultipleAccessingFunctions;
+
+ /// HasNonInstructionUser - Set to true if this global has a user that is not
+ /// an instruction (e.g. a constant expr or GV initializer).
+ bool HasNonInstructionUser;
+
+ /// HasPHIUser - Set to true if this global has a user that is a PHI node.
+ bool HasPHIUser;
+
+ /// isNotSuitableForSRA - Keep track of whether any SRA preventing users of
+ /// the global exist. Such users include GEP instruction with variable
+ /// indexes, and non-gep/load/store users like constant expr casts.
+ bool isNotSuitableForSRA;
+
+ GlobalStatus() : isLoaded(false), StoredType(NotStored), StoredOnceValue(0),
+ AccessingFunction(0), HasMultipleAccessingFunctions(false),
+ HasNonInstructionUser(false), HasPHIUser(false),
+ isNotSuitableForSRA(false) {}
+};
+
+
+
+/// ConstantIsDead - Return true if the specified constant is (transitively)
+/// dead. The constant may be used by other constants (e.g. constant arrays and
+/// constant exprs) as long as they are dead, but it cannot be used by anything
+/// else.
+static bool ConstantIsDead(Constant *C) {
+ if (isa<GlobalValue>(C)) return false;
+
+ for (Value::use_iterator UI = C->use_begin(), E = C->use_end(); UI != E; ++UI)
+ if (Constant *CU = dyn_cast<Constant>(*UI)) {
+ if (!ConstantIsDead(CU)) return false;
+ } else
+ return false;
+ return true;
+}
+
+
+/// AnalyzeGlobal - Look at all uses of the global and fill in the GlobalStatus
+/// structure. If the global has its address taken, return true to indicate we
+/// can't do anything with it.
+///
+static bool AnalyzeGlobal(Value *V, GlobalStatus &GS,
+ std::set<PHINode*> &PHIUsers) {
+ for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(*UI)) {
+ GS.HasNonInstructionUser = true;
+
+ if (AnalyzeGlobal(CE, GS, PHIUsers)) return true;
+ if (CE->getOpcode() != Instruction::GetElementPtr)
+ GS.isNotSuitableForSRA = true;
+ else if (!GS.isNotSuitableForSRA) {
+ // Check to see if this ConstantExpr GEP is SRA'able. In particular, we
+ // don't like < 3 operand CE's, and we don't like non-constant integer
+ // indices.
+ if (CE->getNumOperands() < 3 || !CE->getOperand(1)->isNullValue())
+ GS.isNotSuitableForSRA = true;
+ else {
+ for (unsigned i = 1, e = CE->getNumOperands(); i != e; ++i)
+ if (!isa<ConstantInt>(CE->getOperand(i))) {
+ GS.isNotSuitableForSRA = true;
+ break;
+ }
+ }
+ }
+
+ } else if (Instruction *I = dyn_cast<Instruction>(*UI)) {
+ if (!GS.HasMultipleAccessingFunctions) {
+ Function *F = I->getParent()->getParent();
+ if (GS.AccessingFunction == 0)
+ GS.AccessingFunction = F;
+ else if (GS.AccessingFunction != F)
+ GS.HasMultipleAccessingFunctions = true;
+ }
+ if (isa<LoadInst>(I)) {
+ GS.isLoaded = true;
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
+ // Don't allow a store OF the address, only stores TO the address.
+ if (SI->getOperand(0) == V) return true;
+
+ // If this is a direct store to the global (i.e., the global is a scalar
+ // value, not an aggregate), keep more specific information about
+ // stores.
+ if (GS.StoredType != GlobalStatus::isStored)
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(SI->getOperand(1))){
+ Value *StoredVal = SI->getOperand(0);
+ if (StoredVal == GV->getInitializer()) {
+ if (GS.StoredType < GlobalStatus::isInitializerStored)
+ GS.StoredType = GlobalStatus::isInitializerStored;
+ } else if (isa<LoadInst>(StoredVal) &&
+ cast<LoadInst>(StoredVal)->getOperand(0) == GV) {
+ // G = G
+ if (GS.StoredType < GlobalStatus::isInitializerStored)
+ GS.StoredType = GlobalStatus::isInitializerStored;
+ } else if (GS.StoredType < GlobalStatus::isStoredOnce) {
+ GS.StoredType = GlobalStatus::isStoredOnce;
+ GS.StoredOnceValue = StoredVal;
+ } else if (GS.StoredType == GlobalStatus::isStoredOnce &&
+ GS.StoredOnceValue == StoredVal) {
+ // noop.
+ } else {
+ GS.StoredType = GlobalStatus::isStored;
+ }
+ } else {
+ GS.StoredType = GlobalStatus::isStored;
+ }
+ } else if (isa<GetElementPtrInst>(I)) {
+ if (AnalyzeGlobal(I, GS, PHIUsers)) return true;
+
+ // If the first two indices are constants, this can be SRA'd.
+ if (isa<GlobalVariable>(I->getOperand(0))) {
+ if (I->getNumOperands() < 3 || !isa<Constant>(I->getOperand(1)) ||
+ !cast<Constant>(I->getOperand(1))->isNullValue() ||
+ !isa<ConstantInt>(I->getOperand(2)))
+ GS.isNotSuitableForSRA = true;
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(I->getOperand(0))){
+ if (CE->getOpcode() != Instruction::GetElementPtr ||
+ CE->getNumOperands() < 3 || I->getNumOperands() < 2 ||
+ !isa<Constant>(I->getOperand(0)) ||
+ !cast<Constant>(I->getOperand(0))->isNullValue())
+ GS.isNotSuitableForSRA = true;
+ } else {
+ GS.isNotSuitableForSRA = true;
+ }
+ } else if (isa<SelectInst>(I)) {
+ if (AnalyzeGlobal(I, GS, PHIUsers)) return true;
+ GS.isNotSuitableForSRA = true;
+ } else if (PHINode *PN = dyn_cast<PHINode>(I)) {
+ // PHI nodes we can check just like select or GEP instructions, but we
+ // have to be careful about infinite recursion.
+ if (PHIUsers.insert(PN).second) // Not already visited.
+ if (AnalyzeGlobal(I, GS, PHIUsers)) return true;
+ GS.isNotSuitableForSRA = true;
+ GS.HasPHIUser = true;
+ } else if (isa<CmpInst>(I)) {
+ GS.isNotSuitableForSRA = true;
+ } else if (isa<MemCpyInst>(I) || isa<MemMoveInst>(I)) {
+ if (I->getOperand(1) == V)
+ GS.StoredType = GlobalStatus::isStored;
+ if (I->getOperand(2) == V)
+ GS.isLoaded = true;
+ GS.isNotSuitableForSRA = true;
+ } else if (isa<MemSetInst>(I)) {
+ assert(I->getOperand(1) == V && "Memset only takes one pointer!");
+ GS.StoredType = GlobalStatus::isStored;
+ GS.isNotSuitableForSRA = true;
+ } else {
+ return true; // Any other non-load instruction might take address!
+ }
+ } else if (Constant *C = dyn_cast<Constant>(*UI)) {
+ GS.HasNonInstructionUser = true;
+ // We might have a dead and dangling constant hanging off of here.
+ if (!ConstantIsDead(C))
+ return true;
+ } else {
+ GS.HasNonInstructionUser = true;
+ // Otherwise must be some other user.
+ return true;
+ }
+
+ return false;
+}
+
+static Constant *getAggregateConstantElement(Constant *Agg, Constant *Idx) {
+ ConstantInt *CI = dyn_cast<ConstantInt>(Idx);
+ if (!CI) return 0;
+ unsigned IdxV = CI->getZExtValue();
+
+ if (ConstantStruct *CS = dyn_cast<ConstantStruct>(Agg)) {
+ if (IdxV < CS->getNumOperands()) return CS->getOperand(IdxV);
+ } else if (ConstantArray *CA = dyn_cast<ConstantArray>(Agg)) {
+ if (IdxV < CA->getNumOperands()) return CA->getOperand(IdxV);
+ } else if (ConstantVector *CP = dyn_cast<ConstantVector>(Agg)) {
+ if (IdxV < CP->getNumOperands()) return CP->getOperand(IdxV);
+ } else if (isa<ConstantAggregateZero>(Agg)) {
+ if (const StructType *STy = dyn_cast<StructType>(Agg->getType())) {
+ if (IdxV < STy->getNumElements())
+ return Constant::getNullValue(STy->getElementType(IdxV));
+ } else if (const SequentialType *STy =
+ dyn_cast<SequentialType>(Agg->getType())) {
+ return Constant::getNullValue(STy->getElementType());
+ }
+ } else if (isa<UndefValue>(Agg)) {
+ if (const StructType *STy = dyn_cast<StructType>(Agg->getType())) {
+ if (IdxV < STy->getNumElements())
+ return UndefValue::get(STy->getElementType(IdxV));
+ } else if (const SequentialType *STy =
+ dyn_cast<SequentialType>(Agg->getType())) {
+ return UndefValue::get(STy->getElementType());
+ }
+ }
+ return 0;
+}
+
+
+/// CleanupConstantGlobalUsers - We just marked GV constant. Loop over all
+/// users of the global, cleaning up the obvious ones. This is largely just a
+/// quick scan over the use list to clean up the easy and obvious cruft. This
+/// returns true if it made a change.
+static bool CleanupConstantGlobalUsers(Value *V, Constant *Init) {
+ bool Changed = false;
+ for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;) {
+ User *U = *UI++;
+
+ if (LoadInst *LI = dyn_cast<LoadInst>(U)) {
+ if (Init) {
+ // Replace the load with the initializer.
+ LI->replaceAllUsesWith(Init);
+ LI->eraseFromParent();
+ Changed = true;
+ }
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
+ // Store must be unreachable or storing Init into the global.
+ SI->eraseFromParent();
+ Changed = true;
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
+ if (CE->getOpcode() == Instruction::GetElementPtr) {
+ Constant *SubInit = 0;
+ if (Init)
+ SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
+ Changed |= CleanupConstantGlobalUsers(CE, SubInit);
+ } else if (CE->getOpcode() == Instruction::BitCast &&
+ isa<PointerType>(CE->getType())) {
+ // Pointer cast, delete any stores and memsets to the global.
+ Changed |= CleanupConstantGlobalUsers(CE, 0);
+ }
+
+ if (CE->use_empty()) {
+ CE->destroyConstant();
+ Changed = true;
+ }
+ } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(U)) {
+ Constant *SubInit = 0;
+ ConstantExpr *CE =
+ dyn_cast_or_null<ConstantExpr>(ConstantFoldInstruction(GEP));
+ if (Init && CE && CE->getOpcode() == Instruction::GetElementPtr)
+ SubInit = ConstantFoldLoadThroughGEPConstantExpr(Init, CE);
+ Changed |= CleanupConstantGlobalUsers(GEP, SubInit);
+
+ if (GEP->use_empty()) {
+ GEP->eraseFromParent();
+ Changed = true;
+ }
+ } else if (MemIntrinsic *MI = dyn_cast<MemIntrinsic>(U)) { // memset/cpy/mv
+ if (MI->getRawDest() == V) {
+ MI->eraseFromParent();
+ Changed = true;
+ }
+
+ } else if (Constant *C = dyn_cast<Constant>(U)) {
+ // If we have a chain of dead constantexprs or other things dangling from
+ // us, and if they are all dead, nuke them without remorse.
+ if (ConstantIsDead(C)) {
+ C->destroyConstant();
+ // This could have invalidated UI, start over from scratch.
+ CleanupConstantGlobalUsers(V, Init);
+ return true;
+ }
+ }
+ }
+ return Changed;
+}
+
+/// SRAGlobal - Perform scalar replacement of aggregates on the specified global
+/// variable. This opens the door for other optimizations by exposing the
+/// behavior of the program in a more fine-grained way. We have determined that
+/// this transformation is safe already. We return the first global variable we
+/// insert so that the caller can reprocess it.
+static GlobalVariable *SRAGlobal(GlobalVariable *GV) {
+ assert(GV->hasInternalLinkage() && !GV->isConstant());
+ Constant *Init = GV->getInitializer();
+ const Type *Ty = Init->getType();
+
+ std::vector<GlobalVariable*> NewGlobals;
+ Module::GlobalListType &Globals = GV->getParent()->getGlobalList();
+
+ if (const StructType *STy = dyn_cast<StructType>(Ty)) {
+ NewGlobals.reserve(STy->getNumElements());
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i) {
+ Constant *In = getAggregateConstantElement(Init,
+ ConstantInt::get(Type::Int32Ty, i));
+ assert(In && "Couldn't get element of initializer?");
+ GlobalVariable *NGV = new GlobalVariable(STy->getElementType(i), false,
+ GlobalVariable::InternalLinkage,
+ In, GV->getName()+"."+utostr(i),
+ (Module *)NULL,
+ GV->isThreadLocal());
+ Globals.insert(GV, NGV);
+ NewGlobals.push_back(NGV);
+ }
+ } else if (const SequentialType *STy = dyn_cast<SequentialType>(Ty)) {
+ unsigned NumElements = 0;
+ if (const ArrayType *ATy = dyn_cast<ArrayType>(STy))
+ NumElements = ATy->getNumElements();
+ else if (const VectorType *PTy = dyn_cast<VectorType>(STy))
+ NumElements = PTy->getNumElements();
+ else
+ assert(0 && "Unknown aggregate sequential type!");
+
+ if (NumElements > 16 && GV->hasNUsesOrMore(16))
+ return 0; // It's not worth it.
+ NewGlobals.reserve(NumElements);
+ for (unsigned i = 0, e = NumElements; i != e; ++i) {
+ Constant *In = getAggregateConstantElement(Init,
+ ConstantInt::get(Type::Int32Ty, i));
+ assert(In && "Couldn't get element of initializer?");
+
+ GlobalVariable *NGV = new GlobalVariable(STy->getElementType(), false,
+ GlobalVariable::InternalLinkage,
+ In, GV->getName()+"."+utostr(i),
+ (Module *)NULL,
+ GV->isThreadLocal());
+ Globals.insert(GV, NGV);
+ NewGlobals.push_back(NGV);
+ }
+ }
+
+ if (NewGlobals.empty())
+ return 0;
+
+ DOUT << "PERFORMING GLOBAL SRA ON: " << *GV;
+
+ Constant *NullInt = Constant::getNullValue(Type::Int32Ty);
+
+ // Loop over all of the uses of the global, replacing the constantexpr geps,
+ // with smaller constantexpr geps or direct references.
+ while (!GV->use_empty()) {
+ User *GEP = GV->use_back();
+ assert(((isa<ConstantExpr>(GEP) &&
+ cast<ConstantExpr>(GEP)->getOpcode()==Instruction::GetElementPtr)||
+ isa<GetElementPtrInst>(GEP)) && "NonGEP CE's are not SRAable!");
+
+ // Ignore the 1th operand, which has to be zero or else the program is quite
+ // broken (undefined). Get the 2nd operand, which is the structure or array
+ // index.
+ unsigned Val = cast<ConstantInt>(GEP->getOperand(2))->getZExtValue();
+ if (Val >= NewGlobals.size()) Val = 0; // Out of bound array access.
+
+ Value *NewPtr = NewGlobals[Val];
+
+ // Form a shorter GEP if needed.
+ if (GEP->getNumOperands() > 3)
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(GEP)) {
+ SmallVector<Constant*, 8> Idxs;
+ Idxs.push_back(NullInt);
+ for (unsigned i = 3, e = CE->getNumOperands(); i != e; ++i)
+ Idxs.push_back(CE->getOperand(i));
+ NewPtr = ConstantExpr::getGetElementPtr(cast<Constant>(NewPtr),
+ &Idxs[0], Idxs.size());
+ } else {
+ GetElementPtrInst *GEPI = cast<GetElementPtrInst>(GEP);
+ SmallVector<Value*, 8> Idxs;
+ Idxs.push_back(NullInt);
+ for (unsigned i = 3, e = GEPI->getNumOperands(); i != e; ++i)
+ Idxs.push_back(GEPI->getOperand(i));
+ NewPtr = new GetElementPtrInst(NewPtr, &Idxs[0], Idxs.size(),
+ GEPI->getName()+"."+utostr(Val), GEPI);
+ }
+ GEP->replaceAllUsesWith(NewPtr);
+
+ if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(GEP))
+ GEPI->eraseFromParent();
+ else
+ cast<ConstantExpr>(GEP)->destroyConstant();
+ }
+
+ // Delete the old global, now that it is dead.
+ Globals.erase(GV);
+ ++NumSRA;
+
+ // Loop over the new globals array deleting any globals that are obviously
+ // dead. This can arise due to scalarization of a structure or an array that
+ // has elements that are dead.
+ unsigned FirstGlobal = 0;
+ for (unsigned i = 0, e = NewGlobals.size(); i != e; ++i)
+ if (NewGlobals[i]->use_empty()) {
+ Globals.erase(NewGlobals[i]);
+ if (FirstGlobal == i) ++FirstGlobal;
+ }
+
+ return FirstGlobal != NewGlobals.size() ? NewGlobals[FirstGlobal] : 0;
+}
+
+/// AllUsesOfValueWillTrapIfNull - Return true if all users of the specified
+/// value will trap if the value is dynamically null.
+static bool AllUsesOfValueWillTrapIfNull(Value *V) {
+ for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
+ if (isa<LoadInst>(*UI)) {
+ // Will trap.
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
+ if (SI->getOperand(0) == V) {
+ //cerr << "NONTRAPPING USE: " << **UI;
+ return false; // Storing the value.
+ }
+ } else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
+ if (CI->getOperand(0) != V) {
+ //cerr << "NONTRAPPING USE: " << **UI;
+ return false; // Not calling the ptr
+ }
+ } else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) {
+ if (II->getOperand(0) != V) {
+ //cerr << "NONTRAPPING USE: " << **UI;
+ return false; // Not calling the ptr
+ }
+ } else if (CastInst *CI = dyn_cast<CastInst>(*UI)) {
+ if (!AllUsesOfValueWillTrapIfNull(CI)) return false;
+ } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI)) {
+ if (!AllUsesOfValueWillTrapIfNull(GEPI)) return false;
+ } else if (isa<ICmpInst>(*UI) &&
+ isa<ConstantPointerNull>(UI->getOperand(1))) {
+ // Ignore setcc X, null
+ } else {
+ //cerr << "NONTRAPPING USE: " << **UI;
+ return false;
+ }
+ return true;
+}
+
+/// AllUsesOfLoadedValueWillTrapIfNull - Return true if all uses of any loads
+/// from GV will trap if the loaded value is null. Note that this also permits
+/// comparisons of the loaded value against null, as a special case.
+static bool AllUsesOfLoadedValueWillTrapIfNull(GlobalVariable *GV) {
+ for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end(); UI!=E; ++UI)
+ if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) {
+ if (!AllUsesOfValueWillTrapIfNull(LI))
+ return false;
+ } else if (isa<StoreInst>(*UI)) {
+ // Ignore stores to the global.
+ } else {
+ // We don't know or understand this user, bail out.
+ //cerr << "UNKNOWN USER OF GLOBAL!: " << **UI;
+ return false;
+ }
+
+ return true;
+}
+
+static bool OptimizeAwayTrappingUsesOfValue(Value *V, Constant *NewV) {
+ bool Changed = false;
+ for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ) {
+ Instruction *I = cast<Instruction>(*UI++);
+ if (LoadInst *LI = dyn_cast<LoadInst>(I)) {
+ LI->setOperand(0, NewV);
+ Changed = true;
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(I)) {
+ if (SI->getOperand(1) == V) {
+ SI->setOperand(1, NewV);
+ Changed = true;
+ }
+ } else if (isa<CallInst>(I) || isa<InvokeInst>(I)) {
+ if (I->getOperand(0) == V) {
+ // Calling through the pointer! Turn into a direct call, but be careful
+ // that the pointer is not also being passed as an argument.
+ I->setOperand(0, NewV);
+ Changed = true;
+ bool PassedAsArg = false;
+ for (unsigned i = 1, e = I->getNumOperands(); i != e; ++i)
+ if (I->getOperand(i) == V) {
+ PassedAsArg = true;
+ I->setOperand(i, NewV);
+ }
+
+ if (PassedAsArg) {
+ // Being passed as an argument also. Be careful to not invalidate UI!
+ UI = V->use_begin();
+ }
+ }
+ } else if (CastInst *CI = dyn_cast<CastInst>(I)) {
+ Changed |= OptimizeAwayTrappingUsesOfValue(CI,
+ ConstantExpr::getCast(CI->getOpcode(),
+ NewV, CI->getType()));
+ if (CI->use_empty()) {
+ Changed = true;
+ CI->eraseFromParent();
+ }
+ } else if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(I)) {
+ // Should handle GEP here.
+ SmallVector<Constant*, 8> Idxs;
+ Idxs.reserve(GEPI->getNumOperands()-1);
+ for (unsigned i = 1, e = GEPI->getNumOperands(); i != e; ++i)
+ if (Constant *C = dyn_cast<Constant>(GEPI->getOperand(i)))
+ Idxs.push_back(C);
+ else
+ break;
+ if (Idxs.size() == GEPI->getNumOperands()-1)
+ Changed |= OptimizeAwayTrappingUsesOfValue(GEPI,
+ ConstantExpr::getGetElementPtr(NewV, &Idxs[0],
+ Idxs.size()));
+ if (GEPI->use_empty()) {
+ Changed = true;
+ GEPI->eraseFromParent();
+ }
+ }
+ }
+
+ return Changed;
+}
+
+
+/// OptimizeAwayTrappingUsesOfLoads - The specified global has only one non-null
+/// value stored into it. If there are uses of the loaded value that would trap
+/// if the loaded value is dynamically null, then we know that they cannot be
+/// reachable with a null optimize away the load.
+static bool OptimizeAwayTrappingUsesOfLoads(GlobalVariable *GV, Constant *LV) {
+ std::vector<LoadInst*> Loads;
+ bool Changed = false;
+
+ // Replace all uses of loads with uses of uses of the stored value.
+ for (Value::use_iterator GUI = GV->use_begin(), E = GV->use_end();
+ GUI != E; ++GUI)
+ if (LoadInst *LI = dyn_cast<LoadInst>(*GUI)) {
+ Loads.push_back(LI);
+ Changed |= OptimizeAwayTrappingUsesOfValue(LI, LV);
+ } else {
+ // If we get here we could have stores, selects, or phi nodes whose values
+ // are loaded.
+ assert((isa<StoreInst>(*GUI) || isa<PHINode>(*GUI) ||
+ isa<SelectInst>(*GUI)) &&
+ "Only expect load and stores!");
+ }
+
+ if (Changed) {
+ DOUT << "OPTIMIZED LOADS FROM STORED ONCE POINTER: " << *GV;
+ ++NumGlobUses;
+ }
+
+ // Delete all of the loads we can, keeping track of whether we nuked them all!
+ bool AllLoadsGone = true;
+ while (!Loads.empty()) {
+ LoadInst *L = Loads.back();
+ if (L->use_empty()) {
+ L->eraseFromParent();
+ Changed = true;
+ } else {
+ AllLoadsGone = false;
+ }
+ Loads.pop_back();
+ }
+
+ // If we nuked all of the loads, then none of the stores are needed either,
+ // nor is the global.
+ if (AllLoadsGone) {
+ DOUT << " *** GLOBAL NOW DEAD!\n";
+ CleanupConstantGlobalUsers(GV, 0);
+ if (GV->use_empty()) {
+ GV->eraseFromParent();
+ ++NumDeleted;
+ }
+ Changed = true;
+ }
+ return Changed;
+}
+
+/// ConstantPropUsersOf - Walk the use list of V, constant folding all of the
+/// instructions that are foldable.
+static void ConstantPropUsersOf(Value *V) {
+ for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; )
+ if (Instruction *I = dyn_cast<Instruction>(*UI++))
+ if (Constant *NewC = ConstantFoldInstruction(I)) {
+ I->replaceAllUsesWith(NewC);
+
+ // Advance UI to the next non-I use to avoid invalidating it!
+ // Instructions could multiply use V.
+ while (UI != E && *UI == I)
+ ++UI;
+ I->eraseFromParent();
+ }
+}
+
+/// OptimizeGlobalAddressOfMalloc - This function takes the specified global
+/// variable, and transforms the program as if it always contained the result of
+/// the specified malloc. Because it is always the result of the specified
+/// malloc, there is no reason to actually DO the malloc. Instead, turn the
+/// malloc into a global, and any loads of GV as uses of the new global.
+static GlobalVariable *OptimizeGlobalAddressOfMalloc(GlobalVariable *GV,
+ MallocInst *MI) {
+ DOUT << "PROMOTING MALLOC GLOBAL: " << *GV << " MALLOC = " << *MI;
+ ConstantInt *NElements = cast<ConstantInt>(MI->getArraySize());
+
+ if (NElements->getZExtValue() != 1) {
+ // If we have an array allocation, transform it to a single element
+ // allocation to make the code below simpler.
+ Type *NewTy = ArrayType::get(MI->getAllocatedType(),
+ NElements->getZExtValue());
+ MallocInst *NewMI =
+ new MallocInst(NewTy, Constant::getNullValue(Type::Int32Ty),
+ MI->getAlignment(), MI->getName(), MI);
+ Value* Indices[2];
+ Indices[0] = Indices[1] = Constant::getNullValue(Type::Int32Ty);
+ Value *NewGEP = new GetElementPtrInst(NewMI, Indices, 2,
+ NewMI->getName()+".el0", MI);
+ MI->replaceAllUsesWith(NewGEP);
+ MI->eraseFromParent();
+ MI = NewMI;
+ }
+
+ // Create the new global variable. The contents of the malloc'd memory is
+ // undefined, so initialize with an undef value.
+ Constant *Init = UndefValue::get(MI->getAllocatedType());
+ GlobalVariable *NewGV = new GlobalVariable(MI->getAllocatedType(), false,
+ GlobalValue::InternalLinkage, Init,
+ GV->getName()+".body",
+ (Module *)NULL,
+ GV->isThreadLocal());
+ GV->getParent()->getGlobalList().insert(GV, NewGV);
+
+ // Anything that used the malloc now uses the global directly.
+ MI->replaceAllUsesWith(NewGV);
+
+ Constant *RepValue = NewGV;
+ if (NewGV->getType() != GV->getType()->getElementType())
+ RepValue = ConstantExpr::getBitCast(RepValue,
+ GV->getType()->getElementType());
+
+ // If there is a comparison against null, we will insert a global bool to
+ // keep track of whether the global was initialized yet or not.
+ GlobalVariable *InitBool =
+ new GlobalVariable(Type::Int1Ty, false, GlobalValue::InternalLinkage,
+ ConstantInt::getFalse(), GV->getName()+".init",
+ (Module *)NULL, GV->isThreadLocal());
+ bool InitBoolUsed = false;
+
+ // Loop over all uses of GV, processing them in turn.
+ std::vector<StoreInst*> Stores;
+ while (!GV->use_empty())
+ if (LoadInst *LI = dyn_cast<LoadInst>(GV->use_back())) {
+ while (!LI->use_empty()) {
+ Use &LoadUse = LI->use_begin().getUse();
+ if (!isa<ICmpInst>(LoadUse.getUser()))
+ LoadUse = RepValue;
+ else {
+ ICmpInst *CI = cast<ICmpInst>(LoadUse.getUser());
+ // Replace the cmp X, 0 with a use of the bool value.
+ Value *LV = new LoadInst(InitBool, InitBool->getName()+".val", CI);
+ InitBoolUsed = true;
+ switch (CI->getPredicate()) {
+ default: assert(0 && "Unknown ICmp Predicate!");
+ case ICmpInst::ICMP_ULT:
+ case ICmpInst::ICMP_SLT:
+ LV = ConstantInt::getFalse(); // X < null -> always false
+ break;
+ case ICmpInst::ICMP_ULE:
+ case ICmpInst::ICMP_SLE:
+ case ICmpInst::ICMP_EQ:
+ LV = BinaryOperator::createNot(LV, "notinit", CI);
+ break;
+ case ICmpInst::ICMP_NE:
+ case ICmpInst::ICMP_UGE:
+ case ICmpInst::ICMP_SGE:
+ case ICmpInst::ICMP_UGT:
+ case ICmpInst::ICMP_SGT:
+ break; // no change.
+ }
+ CI->replaceAllUsesWith(LV);
+ CI->eraseFromParent();
+ }
+ }
+ LI->eraseFromParent();
+ } else {
+ StoreInst *SI = cast<StoreInst>(GV->use_back());
+ // The global is initialized when the store to it occurs.
+ new StoreInst(ConstantInt::getTrue(), InitBool, SI);
+ SI->eraseFromParent();
+ }
+
+ // If the initialization boolean was used, insert it, otherwise delete it.
+ if (!InitBoolUsed) {
+ while (!InitBool->use_empty()) // Delete initializations
+ cast<Instruction>(InitBool->use_back())->eraseFromParent();
+ delete InitBool;
+ } else
+ GV->getParent()->getGlobalList().insert(GV, InitBool);
+
+
+ // Now the GV is dead, nuke it and the malloc.
+ GV->eraseFromParent();
+ MI->eraseFromParent();
+
+ // To further other optimizations, loop over all users of NewGV and try to
+ // constant prop them. This will promote GEP instructions with constant
+ // indices into GEP constant-exprs, which will allow global-opt to hack on it.
+ ConstantPropUsersOf(NewGV);
+ if (RepValue != NewGV)
+ ConstantPropUsersOf(RepValue);
+
+ return NewGV;
+}
+
+/// ValueIsOnlyUsedLocallyOrStoredToOneGlobal - Scan the use-list of V checking
+/// to make sure that there are no complex uses of V. We permit simple things
+/// like dereferencing the pointer, but not storing through the address, unless
+/// it is to the specified global.
+static bool ValueIsOnlyUsedLocallyOrStoredToOneGlobal(Instruction *V,
+ GlobalVariable *GV) {
+ for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI)
+ if (isa<LoadInst>(*UI) || isa<CmpInst>(*UI)) {
+ // Fine, ignore.
+ } else if (StoreInst *SI = dyn_cast<StoreInst>(*UI)) {
+ if (SI->getOperand(0) == V && SI->getOperand(1) != GV)
+ return false; // Storing the pointer itself... bad.
+ // Otherwise, storing through it, or storing into GV... fine.
+ } else if (isa<GetElementPtrInst>(*UI) || isa<SelectInst>(*UI)) {
+ if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(cast<Instruction>(*UI),GV))
+ return false;
+ } else {
+ return false;
+ }
+ return true;
+}
+
+/// ReplaceUsesOfMallocWithGlobal - The Alloc pointer is stored into GV
+/// somewhere. Transform all uses of the allocation into loads from the
+/// global and uses of the resultant pointer. Further, delete the store into
+/// GV. This assumes that these value pass the
+/// 'ValueIsOnlyUsedLocallyOrStoredToOneGlobal' predicate.
+static void ReplaceUsesOfMallocWithGlobal(Instruction *Alloc,
+ GlobalVariable *GV) {
+ while (!Alloc->use_empty()) {
+ Instruction *U = Alloc->use_back();
+ if (StoreInst *SI = dyn_cast<StoreInst>(U)) {
+ // If this is the store of the allocation into the global, remove it.
+ if (SI->getOperand(1) == GV) {
+ SI->eraseFromParent();
+ continue;
+ }
+ }
+
+ // Insert a load from the global, and use it instead of the malloc.
+ Value *NL = new LoadInst(GV, GV->getName()+".val", U);
+ U->replaceUsesOfWith(Alloc, NL);
+ }
+}
+
+/// GlobalLoadUsesSimpleEnoughForHeapSRA - If all users of values loaded from
+/// GV are simple enough to perform HeapSRA, return true.
+static bool GlobalLoadUsesSimpleEnoughForHeapSRA(GlobalVariable *GV) {
+ for (Value::use_iterator UI = GV->use_begin(), E = GV->use_end(); UI != E;
+ ++UI)
+ if (LoadInst *LI = dyn_cast<LoadInst>(*UI)) {
+ // We permit two users of the load: setcc comparing against the null
+ // pointer, and a getelementptr of a specific form.
+ for (Value::use_iterator UI = LI->use_begin(), E = LI->use_end(); UI != E;
+ ++UI) {
+ // Comparison against null is ok.
+ if (ICmpInst *ICI = dyn_cast<ICmpInst>(*UI)) {
+ if (!isa<ConstantPointerNull>(ICI->getOperand(1)))
+ return false;
+ continue;
+ }
+
+ // getelementptr is also ok, but only a simple form.
+ GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(*UI);
+ if (!GEPI) return false;
+
+ // Must index into the array and into the struct.
+ if (GEPI->getNumOperands() < 3)
+ return false;
+
+ // Otherwise the GEP is ok.
+ continue;
+ }
+ }
+ return true;
+}
+
+/// RewriteUsesOfLoadForHeapSRoA - We are performing Heap SRoA on a global. Ptr
+/// is a value loaded from the global. Eliminate all uses of Ptr, making them
+/// use FieldGlobals instead. All uses of loaded values satisfy
+/// GlobalLoadUsesSimpleEnoughForHeapSRA.
+static void RewriteUsesOfLoadForHeapSRoA(LoadInst *Ptr,
+ const std::vector<GlobalVariable*> &FieldGlobals) {
+ std::vector<Value *> InsertedLoadsForPtr;
+ //InsertedLoadsForPtr.resize(FieldGlobals.size());
+ while (!Ptr->use_empty()) {
+ Instruction *User = Ptr->use_back();
+
+ // If this is a comparison against null, handle it.
+ if (ICmpInst *SCI = dyn_cast<ICmpInst>(User)) {
+ assert(isa<ConstantPointerNull>(SCI->getOperand(1)));
+ // If we have a setcc of the loaded pointer, we can use a setcc of any
+ // field.
+ Value *NPtr;
+ if (InsertedLoadsForPtr.empty()) {
+ NPtr = new LoadInst(FieldGlobals[0], Ptr->getName()+".f0", Ptr);
+ InsertedLoadsForPtr.push_back(Ptr);
+ } else {
+ NPtr = InsertedLoadsForPtr.back();
+ }
+
+ Value *New = new ICmpInst(SCI->getPredicate(), NPtr,
+ Constant::getNullValue(NPtr->getType()),
+ SCI->getName(), SCI);
+ SCI->replaceAllUsesWith(New);
+ SCI->eraseFromParent();
+ continue;
+ }
+
+ // Otherwise, this should be: 'getelementptr Ptr, Idx, uint FieldNo ...'
+ GetElementPtrInst *GEPI = cast<GetElementPtrInst>(User);
+ assert(GEPI->getNumOperands() >= 3 && isa<ConstantInt>(GEPI->getOperand(2))
+ && "Unexpected GEPI!");
+
+ // Load the pointer for this field.
+ unsigned FieldNo = cast<ConstantInt>(GEPI->getOperand(2))->getZExtValue();
+ if (InsertedLoadsForPtr.size() <= FieldNo)
+ InsertedLoadsForPtr.resize(FieldNo+1);
+ if (InsertedLoadsForPtr[FieldNo] == 0)
+ InsertedLoadsForPtr[FieldNo] = new LoadInst(FieldGlobals[FieldNo],
+ Ptr->getName()+".f" +
+ utostr(FieldNo), Ptr);
+ Value *NewPtr = InsertedLoadsForPtr[FieldNo];
+
+ // Create the new GEP idx vector.
+ SmallVector<Value*, 8> GEPIdx;
+ GEPIdx.push_back(GEPI->getOperand(1));
+ GEPIdx.append(GEPI->op_begin()+3, GEPI->op_end());
+
+ Value *NGEPI = new GetElementPtrInst(NewPtr, &GEPIdx[0], GEPIdx.size(),
+ GEPI->getName(), GEPI);
+ GEPI->replaceAllUsesWith(NGEPI);
+ GEPI->eraseFromParent();
+ }
+}
+
+/// PerformHeapAllocSRoA - MI is an allocation of an array of structures. Break
+/// it up into multiple allocations of arrays of the fields.
+static GlobalVariable *PerformHeapAllocSRoA(GlobalVariable *GV, MallocInst *MI){
+ DOUT << "SROA HEAP ALLOC: " << *GV << " MALLOC = " << *MI;
+ const StructType *STy = cast<StructType>(MI->getAllocatedType());
+
+ // There is guaranteed to be at least one use of the malloc (storing
+ // it into GV). If there are other uses, change them to be uses of
+ // the global to simplify later code. This also deletes the store
+ // into GV.
+ ReplaceUsesOfMallocWithGlobal(MI, GV);
+
+ // Okay, at this point, there are no users of the malloc. Insert N
+ // new mallocs at the same place as MI, and N globals.
+ std::vector<GlobalVariable*> FieldGlobals;
+ std::vector<MallocInst*> FieldMallocs;
+
+ for (unsigned FieldNo = 0, e = STy->getNumElements(); FieldNo != e;++FieldNo){
+ const Type *FieldTy = STy->getElementType(FieldNo);
+ const Type *PFieldTy = PointerType::get(FieldTy);
+
+ GlobalVariable *NGV =
+ new GlobalVariable(PFieldTy, false, GlobalValue::InternalLinkage,
+ Constant::getNullValue(PFieldTy),
+ GV->getName() + ".f" + utostr(FieldNo), GV,
+ GV->isThreadLocal());
+ FieldGlobals.push_back(NGV);
+
+ MallocInst *NMI = new MallocInst(FieldTy, MI->getArraySize(),
+ MI->getName() + ".f" + utostr(FieldNo),MI);
+ FieldMallocs.push_back(NMI);
+ new StoreInst(NMI, NGV, MI);
+ }
+
+ // The tricky aspect of this transformation is handling the case when malloc
+ // fails. In the original code, malloc failing would set the result pointer
+ // of malloc to null. In this case, some mallocs could succeed and others
+ // could fail. As such, we emit code that looks like this:
+ // F0 = malloc(field0)
+ // F1 = malloc(field1)
+ // F2 = malloc(field2)
+ // if (F0 == 0 || F1 == 0 || F2 == 0) {
+ // if (F0) { free(F0); F0 = 0; }
+ // if (F1) { free(F1); F1 = 0; }
+ // if (F2) { free(F2); F2 = 0; }
+ // }
+ Value *RunningOr = 0;
+ for (unsigned i = 0, e = FieldMallocs.size(); i != e; ++i) {
+ Value *Cond = new ICmpInst(ICmpInst::ICMP_EQ, FieldMallocs[i],
+ Constant::getNullValue(FieldMallocs[i]->getType()),
+ "isnull", MI);
+ if (!RunningOr)
+ RunningOr = Cond; // First seteq
+ else
+ RunningOr = BinaryOperator::createOr(RunningOr, Cond, "tmp", MI);
+ }
+
+ // Split the basic block at the old malloc.
+ BasicBlock *OrigBB = MI->getParent();
+ BasicBlock *ContBB = OrigBB->splitBasicBlock(MI, "malloc_cont");
+
+ // Create the block to check the first condition. Put all these blocks at the
+ // end of the function as they are unlikely to be executed.
+ BasicBlock *NullPtrBlock = new BasicBlock("malloc_ret_null",
+ OrigBB->getParent());
+
+ // Remove the uncond branch from OrigBB to ContBB, turning it into a cond
+ // branch on RunningOr.
+ OrigBB->getTerminator()->eraseFromParent();
+ new BranchInst(NullPtrBlock, ContBB, RunningOr, OrigBB);
+
+ // Within the NullPtrBlock, we need to emit a comparison and branch for each
+ // pointer, because some may be null while others are not.
+ for (unsigned i = 0, e = FieldGlobals.size(); i != e; ++i) {
+ Value *GVVal = new LoadInst(FieldGlobals[i], "tmp", NullPtrBlock);
+ Value *Cmp = new ICmpInst(ICmpInst::ICMP_NE, GVVal,
+ Constant::getNullValue(GVVal->getType()),
+ "tmp", NullPtrBlock);
+ BasicBlock *FreeBlock = new BasicBlock("free_it", OrigBB->getParent());
+ BasicBlock *NextBlock = new BasicBlock("next", OrigBB->getParent());
+ new BranchInst(FreeBlock, NextBlock, Cmp, NullPtrBlock);
+
+ // Fill in FreeBlock.
+ new FreeInst(GVVal, FreeBlock);
+ new StoreInst(Constant::getNullValue(GVVal->getType()), FieldGlobals[i],
+ FreeBlock);
+ new BranchInst(NextBlock, FreeBlock);
+
+ NullPtrBlock = NextBlock;
+ }
+
+ new BranchInst(ContBB, NullPtrBlock);
+
+
+ // MI is no longer needed, remove it.
+ MI->eraseFromParent();
+
+
+ // Okay, the malloc site is completely handled. All of the uses of GV are now
+ // loads, and all uses of those loads are simple. Rewrite them to use loads
+ // of the per-field globals instead.
+ while (!GV->use_empty()) {
+ if (LoadInst *LI = dyn_cast<LoadInst>(GV->use_back())) {
+ RewriteUsesOfLoadForHeapSRoA(LI, FieldGlobals);
+ LI->eraseFromParent();
+ } else {
+ // Must be a store of null.
+ StoreInst *SI = cast<StoreInst>(GV->use_back());
+ assert(isa<Constant>(SI->getOperand(0)) &&
+ cast<Constant>(SI->getOperand(0))->isNullValue() &&
+ "Unexpected heap-sra user!");
+
+ // Insert a store of null into each global.
+ for (unsigned i = 0, e = FieldGlobals.size(); i != e; ++i) {
+ Constant *Null =
+ Constant::getNullValue(FieldGlobals[i]->getType()->getElementType());
+ new StoreInst(Null, FieldGlobals[i], SI);
+ }
+ // Erase the original store.
+ SI->eraseFromParent();
+ }
+ }
+
+ // The old global is now dead, remove it.
+ GV->eraseFromParent();
+
+ ++NumHeapSRA;
+ return FieldGlobals[0];
+}
+
+
+// OptimizeOnceStoredGlobal - Try to optimize globals based on the knowledge
+// that only one value (besides its initializer) is ever stored to the global.
+static bool OptimizeOnceStoredGlobal(GlobalVariable *GV, Value *StoredOnceVal,
+ Module::global_iterator &GVI,
+ TargetData &TD) {
+ if (CastInst *CI = dyn_cast<CastInst>(StoredOnceVal))
+ StoredOnceVal = CI->getOperand(0);
+ else if (GetElementPtrInst *GEPI =dyn_cast<GetElementPtrInst>(StoredOnceVal)){
+ // "getelementptr Ptr, 0, 0, 0" is really just a cast.
+ bool IsJustACast = true;
+ for (unsigned i = 1, e = GEPI->getNumOperands(); i != e; ++i)
+ if (!isa<Constant>(GEPI->getOperand(i)) ||
+ !cast<Constant>(GEPI->getOperand(i))->isNullValue()) {
+ IsJustACast = false;
+ break;
+ }
+ if (IsJustACast)
+ StoredOnceVal = GEPI->getOperand(0);
+ }
+
+ // If we are dealing with a pointer global that is initialized to null and
+ // only has one (non-null) value stored into it, then we can optimize any
+ // users of the loaded value (often calls and loads) that would trap if the
+ // value was null.
+ if (isa<PointerType>(GV->getInitializer()->getType()) &&
+ GV->getInitializer()->isNullValue()) {
+ if (Constant *SOVC = dyn_cast<Constant>(StoredOnceVal)) {
+ if (GV->getInitializer()->getType() != SOVC->getType())
+ SOVC = ConstantExpr::getBitCast(SOVC, GV->getInitializer()->getType());
+
+ // Optimize away any trapping uses of the loaded value.
+ if (OptimizeAwayTrappingUsesOfLoads(GV, SOVC))
+ return true;
+ } else if (MallocInst *MI = dyn_cast<MallocInst>(StoredOnceVal)) {
+ // If this is a malloc of an abstract type, don't touch it.
+ if (!MI->getAllocatedType()->isSized())
+ return false;
+
+ // We can't optimize this global unless all uses of it are *known* to be
+ // of the malloc value, not of the null initializer value (consider a use
+ // that compares the global's value against zero to see if the malloc has
+ // been reached). To do this, we check to see if all uses of the global
+ // would trap if the global were null: this proves that they must all
+ // happen after the malloc.
+ if (!AllUsesOfLoadedValueWillTrapIfNull(GV))
+ return false;
+
+ // We can't optimize this if the malloc itself is used in a complex way,
+ // for example, being stored into multiple globals. This allows the
+ // malloc to be stored into the specified global, loaded setcc'd, and
+ // GEP'd. These are all things we could transform to using the global
+ // for.
+ if (!ValueIsOnlyUsedLocallyOrStoredToOneGlobal(MI, GV))
+ return false;
+
+
+ // If we have a global that is only initialized with a fixed size malloc,
+ // transform the program to use global memory instead of malloc'd memory.
+ // This eliminates dynamic allocation, avoids an indirection accessing the
+ // data, and exposes the resultant global to further GlobalOpt.
+ if (ConstantInt *NElements = dyn_cast<ConstantInt>(MI->getArraySize())) {
+ // Restrict this transformation to only working on small allocations
+ // (2048 bytes currently), as we don't want to introduce a 16M global or
+ // something.
+ if (NElements->getZExtValue()*
+ TD.getTypeSize(MI->getAllocatedType()) < 2048) {
+ GVI = OptimizeGlobalAddressOfMalloc(GV, MI);
+ return true;
+ }
+ }
+
+ // If the allocation is an array of structures, consider transforming this
+ // into multiple malloc'd arrays, one for each field. This is basically
+ // SRoA for malloc'd memory.
+ if (const StructType *AllocTy =
+ dyn_cast<StructType>(MI->getAllocatedType())) {
+ // This the structure has an unreasonable number of fields, leave it
+ // alone.
+ if (AllocTy->getNumElements() <= 16 && AllocTy->getNumElements() > 0 &&
+ GlobalLoadUsesSimpleEnoughForHeapSRA(GV)) {
+ GVI = PerformHeapAllocSRoA(GV, MI);
+ return true;
+ }
+ }
+ }
+ }
+
+ return false;
+}
+
+/// ShrinkGlobalToBoolean - At this point, we have learned that the only two
+/// values ever stored into GV are its initializer and OtherVal.
+static void ShrinkGlobalToBoolean(GlobalVariable *GV, Constant *OtherVal) {
+ // Create the new global, initializing it to false.
+ GlobalVariable *NewGV = new GlobalVariable(Type::Int1Ty, false,
+ GlobalValue::InternalLinkage, ConstantInt::getFalse(),
+ GV->getName()+".b",
+ (Module *)NULL,
+ GV->isThreadLocal());
+ GV->getParent()->getGlobalList().insert(GV, NewGV);
+
+ Constant *InitVal = GV->getInitializer();
+ assert(InitVal->getType() != Type::Int1Ty && "No reason to shrink to bool!");
+
+ // If initialized to zero and storing one into the global, we can use a cast
+ // instead of a select to synthesize the desired value.
+ bool IsOneZero = false;
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(OtherVal))
+ IsOneZero = InitVal->isNullValue() && CI->isOne();
+
+ while (!GV->use_empty()) {
+ Instruction *UI = cast<Instruction>(GV->use_back());
+ if (StoreInst *SI = dyn_cast<StoreInst>(UI)) {
+ // Change the store into a boolean store.
+ bool StoringOther = SI->getOperand(0) == OtherVal;
+ // Only do this if we weren't storing a loaded value.
+ Value *StoreVal;
+ if (StoringOther || SI->getOperand(0) == InitVal)
+ StoreVal = ConstantInt::get(Type::Int1Ty, StoringOther);
+ else {
+ // Otherwise, we are storing a previously loaded copy. To do this,
+ // change the copy from copying the original value to just copying the
+ // bool.
+ Instruction *StoredVal = cast<Instruction>(SI->getOperand(0));
+
+ // If we're already replaced the input, StoredVal will be a cast or
+ // select instruction. If not, it will be a load of the original
+ // global.
+ if (LoadInst *LI = dyn_cast<LoadInst>(StoredVal)) {
+ assert(LI->getOperand(0) == GV && "Not a copy!");
+ // Insert a new load, to preserve the saved value.
+ StoreVal = new LoadInst(NewGV, LI->getName()+".b", LI);
+ } else {
+ assert((isa<CastInst>(StoredVal) || isa<SelectInst>(StoredVal)) &&
+ "This is not a form that we understand!");
+ StoreVal = StoredVal->getOperand(0);
+ assert(isa<LoadInst>(StoreVal) && "Not a load of NewGV!");
+ }
+ }
+ new StoreInst(StoreVal, NewGV, SI);
+ } else if (!UI->use_empty()) {
+ // Change the load into a load of bool then a select.
+ LoadInst *LI = cast<LoadInst>(UI);
+ LoadInst *NLI = new LoadInst(NewGV, LI->getName()+".b", LI);
+ Value *NSI;
+ if (IsOneZero)
+ NSI = new ZExtInst(NLI, LI->getType(), "", LI);
+ else
+ NSI = new SelectInst(NLI, OtherVal, InitVal, "", LI);
+ NSI->takeName(LI);
+ LI->replaceAllUsesWith(NSI);
+ }
+ UI->eraseFromParent();
+ }
+
+ GV->eraseFromParent();
+}
+
+
+/// ProcessInternalGlobal - Analyze the specified global variable and optimize
+/// it if possible. If we make a change, return true.
+bool GlobalOpt::ProcessInternalGlobal(GlobalVariable *GV,
+ Module::global_iterator &GVI) {
+ std::set<PHINode*> PHIUsers;
+ GlobalStatus GS;
+ GV->removeDeadConstantUsers();
+
+ if (GV->use_empty()) {
+ DOUT << "GLOBAL DEAD: " << *GV;
+ GV->eraseFromParent();
+ ++NumDeleted;
+ return true;
+ }
+
+ if (!AnalyzeGlobal(GV, GS, PHIUsers)) {
+#if 0
+ cerr << "Global: " << *GV;
+ cerr << " isLoaded = " << GS.isLoaded << "\n";
+ cerr << " StoredType = ";
+ switch (GS.StoredType) {
+ case GlobalStatus::NotStored: cerr << "NEVER STORED\n"; break;
+ case GlobalStatus::isInitializerStored: cerr << "INIT STORED\n"; break;
+ case GlobalStatus::isStoredOnce: cerr << "STORED ONCE\n"; break;
+ case GlobalStatus::isStored: cerr << "stored\n"; break;
+ }
+ if (GS.StoredType == GlobalStatus::isStoredOnce && GS.StoredOnceValue)
+ cerr << " StoredOnceValue = " << *GS.StoredOnceValue << "\n";
+ if (GS.AccessingFunction && !GS.HasMultipleAccessingFunctions)
+ cerr << " AccessingFunction = " << GS.AccessingFunction->getName()
+ << "\n";
+ cerr << " HasMultipleAccessingFunctions = "
+ << GS.HasMultipleAccessingFunctions << "\n";
+ cerr << " HasNonInstructionUser = " << GS.HasNonInstructionUser<<"\n";
+ cerr << " isNotSuitableForSRA = " << GS.isNotSuitableForSRA << "\n";
+ cerr << "\n";
+#endif
+
+ // If this is a first class global and has only one accessing function
+ // and this function is main (which we know is not recursive we can make
+ // this global a local variable) we replace the global with a local alloca
+ // in this function.
+ //
+ // NOTE: It doesn't make sense to promote non first class types since we
+ // are just replacing static memory to stack memory.
+ if (!GS.HasMultipleAccessingFunctions &&
+ GS.AccessingFunction && !GS.HasNonInstructionUser &&
+ GV->getType()->getElementType()->isFirstClassType() &&
+ GS.AccessingFunction->getName() == "main" &&
+ GS.AccessingFunction->hasExternalLinkage()) {
+ DOUT << "LOCALIZING GLOBAL: " << *GV;
+ Instruction* FirstI = GS.AccessingFunction->getEntryBlock().begin();
+ const Type* ElemTy = GV->getType()->getElementType();
+ // FIXME: Pass Global's alignment when globals have alignment
+ AllocaInst* Alloca = new AllocaInst(ElemTy, NULL, GV->getName(), FirstI);
+ if (!isa<UndefValue>(GV->getInitializer()))
+ new StoreInst(GV->getInitializer(), Alloca, FirstI);
+
+ GV->replaceAllUsesWith(Alloca);
+ GV->eraseFromParent();
+ ++NumLocalized;
+ return true;
+ }
+
+ // If the global is never loaded (but may be stored to), it is dead.
+ // Delete it now.
+ if (!GS.isLoaded) {
+ DOUT << "GLOBAL NEVER LOADED: " << *GV;
+
+ // Delete any stores we can find to the global. We may not be able to
+ // make it completely dead though.
+ bool Changed = CleanupConstantGlobalUsers(GV, GV->getInitializer());
+
+ // If the global is dead now, delete it.
+ if (GV->use_empty()) {
+ GV->eraseFromParent();
+ ++NumDeleted;
+ Changed = true;
+ }
+ return Changed;
+
+ } else if (GS.StoredType <= GlobalStatus::isInitializerStored) {
+ DOUT << "MARKING CONSTANT: " << *GV;
+ GV->setConstant(true);
+
+ // Clean up any obviously simplifiable users now.
+ CleanupConstantGlobalUsers(GV, GV->getInitializer());
+
+ // If the global is dead now, just nuke it.
+ if (GV->use_empty()) {
+ DOUT << " *** Marking constant allowed us to simplify "
+ << "all users and delete global!\n";
+ GV->eraseFromParent();
+ ++NumDeleted;
+ }
+
+ ++NumMarked;
+ return true;
+ } else if (!GS.isNotSuitableForSRA &&
+ !GV->getInitializer()->getType()->isFirstClassType()) {
+ if (GlobalVariable *FirstNewGV = SRAGlobal(GV)) {
+ GVI = FirstNewGV; // Don't skip the newly produced globals!
+ return true;
+ }
+ } else if (GS.StoredType == GlobalStatus::isStoredOnce) {
+ // If the initial value for the global was an undef value, and if only
+ // one other value was stored into it, we can just change the
+ // initializer to be an undef value, then delete all stores to the
+ // global. This allows us to mark it constant.
+ if (Constant *SOVConstant = dyn_cast<Constant>(GS.StoredOnceValue))
+ if (isa<UndefValue>(GV->getInitializer())) {
+ // Change the initial value here.
+ GV->setInitializer(SOVConstant);
+
+ // Clean up any obviously simplifiable users now.
+ CleanupConstantGlobalUsers(GV, GV->getInitializer());
+
+ if (GV->use_empty()) {
+ DOUT << " *** Substituting initializer allowed us to "
+ << "simplify all users and delete global!\n";
+ GV->eraseFromParent();
+ ++NumDeleted;
+ } else {
+ GVI = GV;
+ }
+ ++NumSubstitute;
+ return true;
+ }
+
+ // Try to optimize globals based on the knowledge that only one value
+ // (besides its initializer) is ever stored to the global.
+ if (OptimizeOnceStoredGlobal(GV, GS.StoredOnceValue, GVI,
+ getAnalysis<TargetData>()))
+ return true;
+
+ // Otherwise, if the global was not a boolean, we can shrink it to be a
+ // boolean.
+ if (Constant *SOVConstant = dyn_cast<Constant>(GS.StoredOnceValue))
+ if (GV->getType()->getElementType() != Type::Int1Ty &&
+ !GV->getType()->getElementType()->isFloatingPoint() &&
+ !isa<VectorType>(GV->getType()->getElementType()) &&
+ !GS.HasPHIUser && !GS.isNotSuitableForSRA) {
+ DOUT << " *** SHRINKING TO BOOL: " << *GV;
+ ShrinkGlobalToBoolean(GV, SOVConstant);
+ ++NumShrunkToBool;
+ return true;
+ }
+ }
+ }
+ return false;
+}
+
+/// OnlyCalledDirectly - Return true if the specified function is only called
+/// directly. In other words, its address is never taken.
+static bool OnlyCalledDirectly(Function *F) {
+ for (Value::use_iterator UI = F->use_begin(), E = F->use_end(); UI != E;++UI){
+ Instruction *User = dyn_cast<Instruction>(*UI);
+ if (!User) return false;
+ if (!isa<CallInst>(User) && !isa<InvokeInst>(User)) return false;
+
+ // See if the function address is passed as an argument.
+ for (unsigned i = 1, e = User->getNumOperands(); i != e; ++i)
+ if (User->getOperand(i) == F) return false;
+ }
+ return true;
+}
+
+/// ChangeCalleesToFastCall - Walk all of the direct calls of the specified
+/// function, changing them to FastCC.
+static void ChangeCalleesToFastCall(Function *F) {
+ for (Value::use_iterator UI = F->use_begin(), E = F->use_end(); UI != E;++UI){
+ Instruction *User = cast<Instruction>(*UI);
+ if (CallInst *CI = dyn_cast<CallInst>(User))
+ CI->setCallingConv(CallingConv::Fast);
+ else
+ cast<InvokeInst>(User)->setCallingConv(CallingConv::Fast);
+ }
+}
+
+bool GlobalOpt::OptimizeFunctions(Module &M) {
+ bool Changed = false;
+ // Optimize functions.
+ for (Module::iterator FI = M.begin(), E = M.end(); FI != E; ) {
+ Function *F = FI++;
+ F->removeDeadConstantUsers();
+ if (F->use_empty() && (F->hasInternalLinkage() ||
+ F->hasLinkOnceLinkage())) {
+ M.getFunctionList().erase(F);
+ Changed = true;
+ ++NumFnDeleted;
+ } else if (F->hasInternalLinkage() &&
+ F->getCallingConv() == CallingConv::C && !F->isVarArg() &&
+ OnlyCalledDirectly(F)) {
+ // If this function has C calling conventions, is not a varargs
+ // function, and is only called directly, promote it to use the Fast
+ // calling convention.
+ F->setCallingConv(CallingConv::Fast);
+ ChangeCalleesToFastCall(F);
+ ++NumFastCallFns;
+ Changed = true;
+ }
+ }
+ return Changed;
+}
+
+bool GlobalOpt::OptimizeGlobalVars(Module &M) {
+ bool Changed = false;
+ for (Module::global_iterator GVI = M.global_begin(), E = M.global_end();
+ GVI != E; ) {
+ GlobalVariable *GV = GVI++;
+ if (!GV->isConstant() && GV->hasInternalLinkage() &&
+ GV->hasInitializer())
+ Changed |= ProcessInternalGlobal(GV, GVI);
+ }
+ return Changed;
+}
+
+/// FindGlobalCtors - Find the llvm.globalctors list, verifying that all
+/// initializers have an init priority of 65535.
+GlobalVariable *GlobalOpt::FindGlobalCtors(Module &M) {
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
+ if (I->getName() == "llvm.global_ctors") {
+ // Found it, verify it's an array of { int, void()* }.
+ const ArrayType *ATy =dyn_cast<ArrayType>(I->getType()->getElementType());
+ if (!ATy) return 0;
+ const StructType *STy = dyn_cast<StructType>(ATy->getElementType());
+ if (!STy || STy->getNumElements() != 2 ||
+ STy->getElementType(0) != Type::Int32Ty) return 0;
+ const PointerType *PFTy = dyn_cast<PointerType>(STy->getElementType(1));
+ if (!PFTy) return 0;
+ const FunctionType *FTy = dyn_cast<FunctionType>(PFTy->getElementType());
+ if (!FTy || FTy->getReturnType() != Type::VoidTy || FTy->isVarArg() ||
+ FTy->getNumParams() != 0)
+ return 0;
+
+ // Verify that the initializer is simple enough for us to handle.
+ if (!I->hasInitializer()) return 0;
+ ConstantArray *CA = dyn_cast<ConstantArray>(I->getInitializer());
+ if (!CA) return 0;
+ for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
+ if (ConstantStruct *CS = dyn_cast<ConstantStruct>(CA->getOperand(i))) {
+ if (isa<ConstantPointerNull>(CS->getOperand(1)))
+ continue;
+
+ // Must have a function or null ptr.
+ if (!isa<Function>(CS->getOperand(1)))
+ return 0;
+
+ // Init priority must be standard.
+ ConstantInt *CI = dyn_cast<ConstantInt>(CS->getOperand(0));
+ if (!CI || CI->getZExtValue() != 65535)
+ return 0;
+ } else {
+ return 0;
+ }
+
+ return I;
+ }
+ return 0;
+}
+
+/// ParseGlobalCtors - Given a llvm.global_ctors list that we can understand,
+/// return a list of the functions and null terminator as a vector.
+static std::vector<Function*> ParseGlobalCtors(GlobalVariable *GV) {
+ ConstantArray *CA = cast<ConstantArray>(GV->getInitializer());
+ std::vector<Function*> Result;
+ Result.reserve(CA->getNumOperands());
+ for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i) {
+ ConstantStruct *CS = cast<ConstantStruct>(CA->getOperand(i));
+ Result.push_back(dyn_cast<Function>(CS->getOperand(1)));
+ }
+ return Result;
+}
+
+/// InstallGlobalCtors - Given a specified llvm.global_ctors list, install the
+/// specified array, returning the new global to use.
+static GlobalVariable *InstallGlobalCtors(GlobalVariable *GCL,
+ const std::vector<Function*> &Ctors) {
+ // If we made a change, reassemble the initializer list.
+ std::vector<Constant*> CSVals;
+ CSVals.push_back(ConstantInt::get(Type::Int32Ty, 65535));
+ CSVals.push_back(0);
+
+ // Create the new init list.
+ std::vector<Constant*> CAList;
+ for (unsigned i = 0, e = Ctors.size(); i != e; ++i) {
+ if (Ctors[i]) {
+ CSVals[1] = Ctors[i];
+ } else {
+ const Type *FTy = FunctionType::get(Type::VoidTy,
+ std::vector<const Type*>(), false);
+ const PointerType *PFTy = PointerType::get(FTy);
+ CSVals[1] = Constant::getNullValue(PFTy);
+ CSVals[0] = ConstantInt::get(Type::Int32Ty, 2147483647);
+ }
+ CAList.push_back(ConstantStruct::get(CSVals));
+ }
+
+ // Create the array initializer.
+ const Type *StructTy =
+ cast<ArrayType>(GCL->getType()->getElementType())->getElementType();
+ Constant *CA = ConstantArray::get(ArrayType::get(StructTy, CAList.size()),
+ CAList);
+
+ // If we didn't change the number of elements, don't create a new GV.
+ if (CA->getType() == GCL->getInitializer()->getType()) {
+ GCL->setInitializer(CA);
+ return GCL;
+ }
+
+ // Create the new global and insert it next to the existing list.
+ GlobalVariable *NGV = new GlobalVariable(CA->getType(), GCL->isConstant(),
+ GCL->getLinkage(), CA, "",
+ (Module *)NULL,
+ GCL->isThreadLocal());
+ GCL->getParent()->getGlobalList().insert(GCL, NGV);
+ NGV->takeName(GCL);
+
+ // Nuke the old list, replacing any uses with the new one.
+ if (!GCL->use_empty()) {
+ Constant *V = NGV;
+ if (V->getType() != GCL->getType())
+ V = ConstantExpr::getBitCast(V, GCL->getType());
+ GCL->replaceAllUsesWith(V);
+ }
+ GCL->eraseFromParent();
+
+ if (Ctors.size())
+ return NGV;
+ else
+ return 0;
+}
+
+
+static Constant *getVal(std::map<Value*, Constant*> &ComputedValues,
+ Value *V) {
+ if (Constant *CV = dyn_cast<Constant>(V)) return CV;
+ Constant *R = ComputedValues[V];
+ assert(R && "Reference to an uncomputed value!");
+ return R;
+}
+
+/// isSimpleEnoughPointerToCommit - Return true if this constant is simple
+/// enough for us to understand. In particular, if it is a cast of something,
+/// we punt. We basically just support direct accesses to globals and GEP's of
+/// globals. This should be kept up to date with CommitValueTo.
+static bool isSimpleEnoughPointerToCommit(Constant *C) {
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
+ if (!GV->hasExternalLinkage() && !GV->hasInternalLinkage())
+ return false; // do not allow weak/linkonce/dllimport/dllexport linkage.
+ return !GV->isDeclaration(); // reject external globals.
+ }
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
+ // Handle a constantexpr gep.
+ if (CE->getOpcode() == Instruction::GetElementPtr &&
+ isa<GlobalVariable>(CE->getOperand(0))) {
+ GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
+ if (!GV->hasExternalLinkage() && !GV->hasInternalLinkage())
+ return false; // do not allow weak/linkonce/dllimport/dllexport linkage.
+ return GV->hasInitializer() &&
+ ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE);
+ }
+ return false;
+}
+
+/// EvaluateStoreInto - Evaluate a piece of a constantexpr store into a global
+/// initializer. This returns 'Init' modified to reflect 'Val' stored into it.
+/// At this point, the GEP operands of Addr [0, OpNo) have been stepped into.
+static Constant *EvaluateStoreInto(Constant *Init, Constant *Val,
+ ConstantExpr *Addr, unsigned OpNo) {
+ // Base case of the recursion.
+ if (OpNo == Addr->getNumOperands()) {
+ assert(Val->getType() == Init->getType() && "Type mismatch!");
+ return Val;
+ }
+
+ if (const StructType *STy = dyn_cast<StructType>(Init->getType())) {
+ std::vector<Constant*> Elts;
+
+ // Break up the constant into its elements.
+ if (ConstantStruct *CS = dyn_cast<ConstantStruct>(Init)) {
+ for (unsigned i = 0, e = CS->getNumOperands(); i != e; ++i)
+ Elts.push_back(CS->getOperand(i));
+ } else if (isa<ConstantAggregateZero>(Init)) {
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
+ Elts.push_back(Constant::getNullValue(STy->getElementType(i)));
+ } else if (isa<UndefValue>(Init)) {
+ for (unsigned i = 0, e = STy->getNumElements(); i != e; ++i)
+ Elts.push_back(UndefValue::get(STy->getElementType(i)));
+ } else {
+ assert(0 && "This code is out of sync with "
+ " ConstantFoldLoadThroughGEPConstantExpr");
+ }
+
+ // Replace the element that we are supposed to.
+ ConstantInt *CU = cast<ConstantInt>(Addr->getOperand(OpNo));
+ unsigned Idx = CU->getZExtValue();
+ assert(Idx < STy->getNumElements() && "Struct index out of range!");
+ Elts[Idx] = EvaluateStoreInto(Elts[Idx], Val, Addr, OpNo+1);
+
+ // Return the modified struct.
+ return ConstantStruct::get(&Elts[0], Elts.size(), STy->isPacked());
+ } else {
+ ConstantInt *CI = cast<ConstantInt>(Addr->getOperand(OpNo));
+ const ArrayType *ATy = cast<ArrayType>(Init->getType());
+
+ // Break up the array into elements.
+ std::vector<Constant*> Elts;
+ if (ConstantArray *CA = dyn_cast<ConstantArray>(Init)) {
+ for (unsigned i = 0, e = CA->getNumOperands(); i != e; ++i)
+ Elts.push_back(CA->getOperand(i));
+ } else if (isa<ConstantAggregateZero>(Init)) {
+ Constant *Elt = Constant::getNullValue(ATy->getElementType());
+ Elts.assign(ATy->getNumElements(), Elt);
+ } else if (isa<UndefValue>(Init)) {
+ Constant *Elt = UndefValue::get(ATy->getElementType());
+ Elts.assign(ATy->getNumElements(), Elt);
+ } else {
+ assert(0 && "This code is out of sync with "
+ " ConstantFoldLoadThroughGEPConstantExpr");
+ }
+
+ assert(CI->getZExtValue() < ATy->getNumElements());
+ Elts[CI->getZExtValue()] =
+ EvaluateStoreInto(Elts[CI->getZExtValue()], Val, Addr, OpNo+1);
+ return ConstantArray::get(ATy, Elts);
+ }
+}
+
+/// CommitValueTo - We have decided that Addr (which satisfies the predicate
+/// isSimpleEnoughPointerToCommit) should get Val as its value. Make it happen.
+static void CommitValueTo(Constant *Val, Constant *Addr) {
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Addr)) {
+ assert(GV->hasInitializer());
+ GV->setInitializer(Val);
+ return;
+ }
+
+ ConstantExpr *CE = cast<ConstantExpr>(Addr);
+ GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
+
+ Constant *Init = GV->getInitializer();
+ Init = EvaluateStoreInto(Init, Val, CE, 2);
+ GV->setInitializer(Init);
+}
+
+/// ComputeLoadResult - Return the value that would be computed by a load from
+/// P after the stores reflected by 'memory' have been performed. If we can't
+/// decide, return null.
+static Constant *ComputeLoadResult(Constant *P,
+ const std::map<Constant*, Constant*> &Memory) {
+ // If this memory location has been recently stored, use the stored value: it
+ // is the most up-to-date.
+ std::map<Constant*, Constant*>::const_iterator I = Memory.find(P);
+ if (I != Memory.end()) return I->second;
+
+ // Access it.
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(P)) {
+ if (GV->hasInitializer())
+ return GV->getInitializer();
+ return 0;
+ }
+
+ // Handle a constantexpr getelementptr.
+ if (ConstantExpr *CE = dyn_cast<ConstantExpr>(P))
+ if (CE->getOpcode() == Instruction::GetElementPtr &&
+ isa<GlobalVariable>(CE->getOperand(0))) {
+ GlobalVariable *GV = cast<GlobalVariable>(CE->getOperand(0));
+ if (GV->hasInitializer())
+ return ConstantFoldLoadThroughGEPConstantExpr(GV->getInitializer(), CE);
+ }
+
+ return 0; // don't know how to evaluate.
+}
+
+/// EvaluateFunction - Evaluate a call to function F, returning true if
+/// successful, false if we can't evaluate it. ActualArgs contains the formal
+/// arguments for the function.
+static bool EvaluateFunction(Function *F, Constant *&RetVal,
+ const std::vector<Constant*> &ActualArgs,
+ std::vector<Function*> &CallStack,
+ std::map<Constant*, Constant*> &MutatedMemory,
+ std::vector<GlobalVariable*> &AllocaTmps) {
+ // Check to see if this function is already executing (recursion). If so,
+ // bail out. TODO: we might want to accept limited recursion.
+ if (std::find(CallStack.begin(), CallStack.end(), F) != CallStack.end())
+ return false;
+
+ CallStack.push_back(F);
+
+ /// Values - As we compute SSA register values, we store their contents here.
+ std::map<Value*, Constant*> Values;
+
+ // Initialize arguments to the incoming values specified.
+ unsigned ArgNo = 0;
+ for (Function::arg_iterator AI = F->arg_begin(), E = F->arg_end(); AI != E;
+ ++AI, ++ArgNo)
+ Values[AI] = ActualArgs[ArgNo];
+
+ /// ExecutedBlocks - We only handle non-looping, non-recursive code. As such,
+ /// we can only evaluate any one basic block at most once. This set keeps
+ /// track of what we have executed so we can detect recursive cases etc.
+ std::set<BasicBlock*> ExecutedBlocks;
+
+ // CurInst - The current instruction we're evaluating.
+ BasicBlock::iterator CurInst = F->begin()->begin();
+
+ // This is the main evaluation loop.
+ while (1) {
+ Constant *InstResult = 0;
+
+ if (StoreInst *SI = dyn_cast<StoreInst>(CurInst)) {
+ if (SI->isVolatile()) return false; // no volatile accesses.
+ Constant *Ptr = getVal(Values, SI->getOperand(1));
+ if (!isSimpleEnoughPointerToCommit(Ptr))
+ // If this is too complex for us to commit, reject it.
+ return false;
+ Constant *Val = getVal(Values, SI->getOperand(0));
+ MutatedMemory[Ptr] = Val;
+ } else if (BinaryOperator *BO = dyn_cast<BinaryOperator>(CurInst)) {
+ InstResult = ConstantExpr::get(BO->getOpcode(),
+ getVal(Values, BO->getOperand(0)),
+ getVal(Values, BO->getOperand(1)));
+ } else if (CmpInst *CI = dyn_cast<CmpInst>(CurInst)) {
+ InstResult = ConstantExpr::getCompare(CI->getPredicate(),
+ getVal(Values, CI->getOperand(0)),
+ getVal(Values, CI->getOperand(1)));
+ } else if (CastInst *CI = dyn_cast<CastInst>(CurInst)) {
+ InstResult = ConstantExpr::getCast(CI->getOpcode(),
+ getVal(Values, CI->getOperand(0)),
+ CI->getType());
+ } else if (SelectInst *SI = dyn_cast<SelectInst>(CurInst)) {
+ InstResult = ConstantExpr::getSelect(getVal(Values, SI->getOperand(0)),
+ getVal(Values, SI->getOperand(1)),
+ getVal(Values, SI->getOperand(2)));
+ } else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(CurInst)) {
+ Constant *P = getVal(Values, GEP->getOperand(0));
+ SmallVector<Constant*, 8> GEPOps;
+ for (unsigned i = 1, e = GEP->getNumOperands(); i != e; ++i)
+ GEPOps.push_back(getVal(Values, GEP->getOperand(i)));
+ InstResult = ConstantExpr::getGetElementPtr(P, &GEPOps[0], GEPOps.size());
+ } else if (LoadInst *LI = dyn_cast<LoadInst>(CurInst)) {
+ if (LI->isVolatile()) return false; // no volatile accesses.
+ InstResult = ComputeLoadResult(getVal(Values, LI->getOperand(0)),
+ MutatedMemory);
+ if (InstResult == 0) return false; // Could not evaluate load.
+ } else if (AllocaInst *AI = dyn_cast<AllocaInst>(CurInst)) {
+ if (AI->isArrayAllocation()) return false; // Cannot handle array allocs.
+ const Type *Ty = AI->getType()->getElementType();
+ AllocaTmps.push_back(new GlobalVariable(Ty, false,
+ GlobalValue::InternalLinkage,
+ UndefValue::get(Ty),
+ AI->getName()));
+ InstResult = AllocaTmps.back();
+ } else if (CallInst *CI = dyn_cast<CallInst>(CurInst)) {
+ // Cannot handle inline asm.
+ if (isa<InlineAsm>(CI->getOperand(0))) return false;
+
+ // Resolve function pointers.
+ Function *Callee = dyn_cast<Function>(getVal(Values, CI->getOperand(0)));
+ if (!Callee) return false; // Cannot resolve.
+
+ std::vector<Constant*> Formals;
+ for (unsigned i = 1, e = CI->getNumOperands(); i != e; ++i)
+ Formals.push_back(getVal(Values, CI->getOperand(i)));
+
+ if (Callee->isDeclaration()) {
+ // If this is a function we can constant fold, do it.
+ if (Constant *C = ConstantFoldCall(Callee, &Formals[0],
+ Formals.size())) {
+ InstResult = C;
+ } else {
+ return false;
+ }
+ } else {
+ if (Callee->getFunctionType()->isVarArg())
+ return false;
+
+ Constant *RetVal;
+
+ // Execute the call, if successful, use the return value.
+ if (!EvaluateFunction(Callee, RetVal, Formals, CallStack,
+ MutatedMemory, AllocaTmps))
+ return false;
+ InstResult = RetVal;
+ }
+ } else if (isa<TerminatorInst>(CurInst)) {
+ BasicBlock *NewBB = 0;
+ if (BranchInst *BI = dyn_cast<BranchInst>(CurInst)) {
+ if (BI->isUnconditional()) {
+ NewBB = BI->getSuccessor(0);
+ } else {
+ ConstantInt *Cond =
+ dyn_cast<ConstantInt>(getVal(Values, BI->getCondition()));
+ if (!Cond) return false; // Cannot determine.
+
+ NewBB = BI->getSuccessor(!Cond->getZExtValue());
+ }
+ } else if (SwitchInst *SI = dyn_cast<SwitchInst>(CurInst)) {
+ ConstantInt *Val =
+ dyn_cast<ConstantInt>(getVal(Values, SI->getCondition()));
+ if (!Val) return false; // Cannot determine.
+ NewBB = SI->getSuccessor(SI->findCaseValue(Val));
+ } else if (ReturnInst *RI = dyn_cast<ReturnInst>(CurInst)) {
+ if (RI->getNumOperands())
+ RetVal = getVal(Values, RI->getOperand(0));
+
+ CallStack.pop_back(); // return from fn.
+ return true; // We succeeded at evaluating this ctor!
+ } else {
+ // invoke, unwind, unreachable.
+ return false; // Cannot handle this terminator.
+ }
+
+ // Okay, we succeeded in evaluating this control flow. See if we have
+ // executed the new block before. If so, we have a looping function,
+ // which we cannot evaluate in reasonable time.
+ if (!ExecutedBlocks.insert(NewBB).second)
+ return false; // looped!
+
+ // Okay, we have never been in this block before. Check to see if there
+ // are any PHI nodes. If so, evaluate them with information about where
+ // we came from.
+ BasicBlock *OldBB = CurInst->getParent();
+ CurInst = NewBB->begin();
+ PHINode *PN;
+ for (; (PN = dyn_cast<PHINode>(CurInst)); ++CurInst)
+ Values[PN] = getVal(Values, PN->getIncomingValueForBlock(OldBB));
+
+ // Do NOT increment CurInst. We know that the terminator had no value.
+ continue;
+ } else {
+ // Did not know how to evaluate this!
+ return false;
+ }
+
+ if (!CurInst->use_empty())
+ Values[CurInst] = InstResult;
+
+ // Advance program counter.
+ ++CurInst;
+ }
+}
+
+/// EvaluateStaticConstructor - Evaluate static constructors in the function, if
+/// we can. Return true if we can, false otherwise.
+static bool EvaluateStaticConstructor(Function *F) {
+ /// MutatedMemory - For each store we execute, we update this map. Loads
+ /// check this to get the most up-to-date value. If evaluation is successful,
+ /// this state is committed to the process.
+ std::map<Constant*, Constant*> MutatedMemory;
+
+ /// AllocaTmps - To 'execute' an alloca, we create a temporary global variable
+ /// to represent its body. This vector is needed so we can delete the
+ /// temporary globals when we are done.
+ std::vector<GlobalVariable*> AllocaTmps;
+
+ /// CallStack - This is used to detect recursion. In pathological situations
+ /// we could hit exponential behavior, but at least there is nothing
+ /// unbounded.
+ std::vector<Function*> CallStack;
+
+ // Call the function.
+ Constant *RetValDummy;
+ bool EvalSuccess = EvaluateFunction(F, RetValDummy, std::vector<Constant*>(),
+ CallStack, MutatedMemory, AllocaTmps);
+ if (EvalSuccess) {
+ // We succeeded at evaluation: commit the result.
+ DOUT << "FULLY EVALUATED GLOBAL CTOR FUNCTION '"
+ << F->getName() << "' to " << MutatedMemory.size()
+ << " stores.\n";
+ for (std::map<Constant*, Constant*>::iterator I = MutatedMemory.begin(),
+ E = MutatedMemory.end(); I != E; ++I)
+ CommitValueTo(I->second, I->first);
+ }
+
+ // At this point, we are done interpreting. If we created any 'alloca'
+ // temporaries, release them now.
+ while (!AllocaTmps.empty()) {
+ GlobalVariable *Tmp = AllocaTmps.back();
+ AllocaTmps.pop_back();
+
+ // If there are still users of the alloca, the program is doing something
+ // silly, e.g. storing the address of the alloca somewhere and using it
+ // later. Since this is undefined, we'll just make it be null.
+ if (!Tmp->use_empty())
+ Tmp->replaceAllUsesWith(Constant::getNullValue(Tmp->getType()));
+ delete Tmp;
+ }
+
+ return EvalSuccess;
+}
+
+
+
+/// OptimizeGlobalCtorsList - Simplify and evaluation global ctors if possible.
+/// Return true if anything changed.
+bool GlobalOpt::OptimizeGlobalCtorsList(GlobalVariable *&GCL) {
+ std::vector<Function*> Ctors = ParseGlobalCtors(GCL);
+ bool MadeChange = false;
+ if (Ctors.empty()) return false;
+
+ // Loop over global ctors, optimizing them when we can.
+ for (unsigned i = 0; i != Ctors.size(); ++i) {
+ Function *F = Ctors[i];
+ // Found a null terminator in the middle of the list, prune off the rest of
+ // the list.
+ if (F == 0) {
+ if (i != Ctors.size()-1) {
+ Ctors.resize(i+1);
+ MadeChange = true;
+ }
+ break;
+ }
+
+ // We cannot simplify external ctor functions.
+ if (F->empty()) continue;
+
+ // If we can evaluate the ctor at compile time, do.
+ if (EvaluateStaticConstructor(F)) {
+ Ctors.erase(Ctors.begin()+i);
+ MadeChange = true;
+ --i;
+ ++NumCtorsEvaluated;
+ continue;
+ }
+ }
+
+ if (!MadeChange) return false;
+
+ GCL = InstallGlobalCtors(GCL, Ctors);
+ return true;
+}
+
+
+bool GlobalOpt::runOnModule(Module &M) {
+ bool Changed = false;
+
+ // Try to find the llvm.globalctors list.
+ GlobalVariable *GlobalCtors = FindGlobalCtors(M);
+
+ bool LocalChange = true;
+ while (LocalChange) {
+ LocalChange = false;
+
+ // Delete functions that are trivially dead, ccc -> fastcc
+ LocalChange |= OptimizeFunctions(M);
+
+ // Optimize global_ctors list.
+ if (GlobalCtors)
+ LocalChange |= OptimizeGlobalCtorsList(GlobalCtors);
+
+ // Optimize non-address-taken globals.
+ LocalChange |= OptimizeGlobalVars(M);
+ Changed |= LocalChange;
+ }
+
+ // TODO: Move all global ctors functions to the end of the module for code
+ // layout.
+
+ return Changed;
+}
diff --git a/lib/Transforms/IPO/IPConstantPropagation.cpp b/lib/Transforms/IPO/IPConstantPropagation.cpp
new file mode 100644
index 0000000..b55e538
--- /dev/null
+++ b/lib/Transforms/IPO/IPConstantPropagation.cpp
@@ -0,0 +1,197 @@
+//===-- IPConstantPropagation.cpp - Propagate constants through calls -----===//
+//
+// 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 pass implements an _extremely_ simple interprocedural constant
+// propagation pass. It could certainly be improved in many different ways,
+// like using a worklist. This pass makes arguments dead, but does not remove
+// them. The existing dead argument elimination pass should be run after this
+// to clean up the mess.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "ipconstprop"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Constants.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/Statistic.h"
+using namespace llvm;
+
+STATISTIC(NumArgumentsProped, "Number of args turned into constants");
+STATISTIC(NumReturnValProped, "Number of return values turned into constants");
+
+namespace {
+ /// IPCP - The interprocedural constant propagation pass
+ ///
+ struct VISIBILITY_HIDDEN IPCP : public ModulePass {
+ static char ID; // Pass identification, replacement for typeid
+ IPCP() : ModulePass((intptr_t)&ID) {}
+
+ bool runOnModule(Module &M);
+ private:
+ bool PropagateConstantsIntoArguments(Function &F);
+ bool PropagateConstantReturn(Function &F);
+ };
+ char IPCP::ID = 0;
+ RegisterPass<IPCP> X("ipconstprop", "Interprocedural constant propagation");
+}
+
+ModulePass *llvm::createIPConstantPropagationPass() { return new IPCP(); }
+
+bool IPCP::runOnModule(Module &M) {
+ bool Changed = false;
+ bool LocalChange = true;
+
+ // FIXME: instead of using smart algorithms, we just iterate until we stop
+ // making changes.
+ while (LocalChange) {
+ LocalChange = false;
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (!I->isDeclaration()) {
+ // Delete any klingons.
+ I->removeDeadConstantUsers();
+ if (I->hasInternalLinkage())
+ LocalChange |= PropagateConstantsIntoArguments(*I);
+ Changed |= PropagateConstantReturn(*I);
+ }
+ Changed |= LocalChange;
+ }
+ return Changed;
+}
+
+/// PropagateConstantsIntoArguments - Look at all uses of the specified
+/// function. If all uses are direct call sites, and all pass a particular
+/// constant in for an argument, propagate that constant in as the argument.
+///
+bool IPCP::PropagateConstantsIntoArguments(Function &F) {
+ if (F.arg_empty() || F.use_empty()) return false; // No arguments? Early exit.
+
+ std::vector<std::pair<Constant*, bool> > ArgumentConstants;
+ ArgumentConstants.resize(F.arg_size());
+
+ unsigned NumNonconstant = 0;
+
+ for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I)
+ if (!isa<Instruction>(*I))
+ return false; // Used by a non-instruction, do not transform
+ else {
+ CallSite CS = CallSite::get(cast<Instruction>(*I));
+ if (CS.getInstruction() == 0 ||
+ CS.getCalledFunction() != &F)
+ return false; // Not a direct call site?
+
+ // Check out all of the potentially constant arguments
+ CallSite::arg_iterator AI = CS.arg_begin();
+ Function::arg_iterator Arg = F.arg_begin();
+ for (unsigned i = 0, e = ArgumentConstants.size(); i != e;
+ ++i, ++AI, ++Arg) {
+ if (*AI == &F) return false; // Passes the function into itself
+
+ if (!ArgumentConstants[i].second) {
+ if (Constant *C = dyn_cast<Constant>(*AI)) {
+ if (!ArgumentConstants[i].first)
+ ArgumentConstants[i].first = C;
+ else if (ArgumentConstants[i].first != C) {
+ // Became non-constant
+ ArgumentConstants[i].second = true;
+ ++NumNonconstant;
+ if (NumNonconstant == ArgumentConstants.size()) return false;
+ }
+ } else if (*AI != &*Arg) { // Ignore recursive calls with same arg
+ // This is not a constant argument. Mark the argument as
+ // non-constant.
+ ArgumentConstants[i].second = true;
+ ++NumNonconstant;
+ if (NumNonconstant == ArgumentConstants.size()) return false;
+ }
+ }
+ }
+ }
+
+ // If we got to this point, there is a constant argument!
+ assert(NumNonconstant != ArgumentConstants.size());
+ Function::arg_iterator AI = F.arg_begin();
+ bool MadeChange = false;
+ for (unsigned i = 0, e = ArgumentConstants.size(); i != e; ++i, ++AI)
+ // Do we have a constant argument!?
+ if (!ArgumentConstants[i].second && !AI->use_empty()) {
+ Value *V = ArgumentConstants[i].first;
+ if (V == 0) V = UndefValue::get(AI->getType());
+ AI->replaceAllUsesWith(V);
+ ++NumArgumentsProped;
+ MadeChange = true;
+ }
+ return MadeChange;
+}
+
+
+// Check to see if this function returns a constant. If so, replace all callers
+// that user the return value with the returned valued. If we can replace ALL
+// callers,
+bool IPCP::PropagateConstantReturn(Function &F) {
+ if (F.getReturnType() == Type::VoidTy)
+ return false; // No return value.
+
+ // Check to see if this function returns a constant.
+ Value *RetVal = 0;
+ for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+ if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator()))
+ if (isa<UndefValue>(RI->getOperand(0))) {
+ // Ignore.
+ } else if (Constant *C = dyn_cast<Constant>(RI->getOperand(0))) {
+ if (RetVal == 0)
+ RetVal = C;
+ else if (RetVal != C)
+ return false; // Does not return the same constant.
+ } else {
+ return false; // Does not return a constant.
+ }
+
+ if (RetVal == 0) RetVal = UndefValue::get(F.getReturnType());
+
+ // If we got here, the function returns a constant value. Loop over all
+ // users, replacing any uses of the return value with the returned constant.
+ bool ReplacedAllUsers = true;
+ bool MadeChange = false;
+ for (Value::use_iterator I = F.use_begin(), E = F.use_end(); I != E; ++I)
+ if (!isa<Instruction>(*I))
+ ReplacedAllUsers = false;
+ else {
+ CallSite CS = CallSite::get(cast<Instruction>(*I));
+ if (CS.getInstruction() == 0 ||
+ CS.getCalledFunction() != &F) {
+ ReplacedAllUsers = false;
+ } else {
+ if (!CS.getInstruction()->use_empty()) {
+ CS.getInstruction()->replaceAllUsesWith(RetVal);
+ MadeChange = true;
+ }
+ }
+ }
+
+ // If we replace all users with the returned constant, and there can be no
+ // other callers of the function, replace the constant being returned in the
+ // function with an undef value.
+ if (ReplacedAllUsers && F.hasInternalLinkage() && !isa<UndefValue>(RetVal)) {
+ Value *RV = UndefValue::get(RetVal->getType());
+ for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
+ if (ReturnInst *RI = dyn_cast<ReturnInst>(BB->getTerminator())) {
+ if (RI->getOperand(0) != RV) {
+ RI->setOperand(0, RV);
+ MadeChange = true;
+ }
+ }
+ }
+
+ if (MadeChange) ++NumReturnValProped;
+ return MadeChange;
+}
diff --git a/lib/Transforms/IPO/IndMemRemoval.cpp b/lib/Transforms/IPO/IndMemRemoval.cpp
new file mode 100644
index 0000000..6b06469
--- /dev/null
+++ b/lib/Transforms/IPO/IndMemRemoval.cpp
@@ -0,0 +1,89 @@
+//===-- IndMemRemoval.cpp - Remove indirect allocations and frees ----------===//
+//
+// 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 pass finds places where memory allocation functions may escape into
+// indirect land. Some transforms are much easier (aka possible) only if free
+// or malloc are not called indirectly.
+// Thus find places where the address of memory functions are taken and construct
+// bounce functions with direct calls of those functions.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "indmemrem"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Pass.h"
+#include "llvm/Module.h"
+#include "llvm/Instructions.h"
+#include "llvm/Type.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Compiler.h"
+using namespace llvm;
+
+STATISTIC(NumBounceSites, "Number of sites modified");
+STATISTIC(NumBounce , "Number of bounce functions created");
+
+namespace {
+ class VISIBILITY_HIDDEN IndMemRemPass : public ModulePass {
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ IndMemRemPass() : ModulePass((intptr_t)&ID) {}
+
+ virtual bool runOnModule(Module &M);
+ };
+ char IndMemRemPass::ID = 0;
+ RegisterPass<IndMemRemPass> X("indmemrem","Indirect Malloc and Free Removal");
+} // end anonymous namespace
+
+
+bool IndMemRemPass::runOnModule(Module &M) {
+ //in Theory, all direct calls of malloc and free should be promoted
+ //to intrinsics. Therefor, this goes through and finds where the
+ //address of free or malloc are taken and replaces those with bounce
+ //functions, ensuring that all malloc and free that might happen
+ //happen through intrinsics.
+ bool changed = false;
+ if (Function* F = M.getFunction("free")) {
+ assert(F->isDeclaration() && "free not external?");
+ if (!F->use_empty()) {
+ Function* FN = new Function(F->getFunctionType(),
+ GlobalValue::LinkOnceLinkage,
+ "free_llvm_bounce", &M);
+ BasicBlock* bb = new BasicBlock("entry",FN);
+ Instruction* R = new ReturnInst(bb);
+ new FreeInst(FN->arg_begin(), R);
+ ++NumBounce;
+ NumBounceSites += F->getNumUses();
+ F->replaceAllUsesWith(FN);
+ changed = true;
+ }
+ }
+ if (Function* F = M.getFunction("malloc")) {
+ assert(F->isDeclaration() && "malloc not external?");
+ if (!F->use_empty()) {
+ Function* FN = new Function(F->getFunctionType(),
+ GlobalValue::LinkOnceLinkage,
+ "malloc_llvm_bounce", &M);
+ BasicBlock* bb = new BasicBlock("entry",FN);
+ Instruction* c = CastInst::createIntegerCast(
+ FN->arg_begin(), Type::Int32Ty, false, "c", bb);
+ Instruction* a = new MallocInst(Type::Int8Ty, c, "m", bb);
+ new ReturnInst(a, bb);
+ ++NumBounce;
+ NumBounceSites += F->getNumUses();
+ F->replaceAllUsesWith(FN);
+ changed = true;
+ }
+ }
+ return changed;
+}
+
+ModulePass *llvm::createIndMemRemPass() {
+ return new IndMemRemPass();
+}
diff --git a/lib/Transforms/IPO/InlineSimple.cpp b/lib/Transforms/IPO/InlineSimple.cpp
new file mode 100644
index 0000000..2157dcd
--- /dev/null
+++ b/lib/Transforms/IPO/InlineSimple.cpp
@@ -0,0 +1,323 @@
+//===- InlineSimple.cpp - Code to perform simple function inlining --------===//
+//
+// 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 implements bottom-up inlining of functions into callees.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "inline"
+#include "llvm/CallingConv.h"
+#include "llvm/Instructions.h"
+#include "llvm/IntrinsicInst.h"
+#include "llvm/Module.h"
+#include "llvm/Type.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Transforms/IPO/InlinerPass.h"
+#include <set>
+
+using namespace llvm;
+
+namespace {
+ struct VISIBILITY_HIDDEN ArgInfo {
+ unsigned ConstantWeight;
+ unsigned AllocaWeight;
+
+ ArgInfo(unsigned CWeight, unsigned AWeight)
+ : ConstantWeight(CWeight), AllocaWeight(AWeight) {}
+ };
+
+ // FunctionInfo - For each function, calculate the size of it in blocks and
+ // instructions.
+ struct VISIBILITY_HIDDEN FunctionInfo {
+ // NumInsts, NumBlocks - Keep track of how large each function is, which is
+ // used to estimate the code size cost of inlining it.
+ unsigned NumInsts, NumBlocks;
+
+ // ArgumentWeights - Each formal argument of the function is inspected to
+ // see if it is used in any contexts where making it a constant or alloca
+ // would reduce the code size. If so, we add some value to the argument
+ // entry here.
+ std::vector<ArgInfo> ArgumentWeights;
+
+ FunctionInfo() : NumInsts(0), NumBlocks(0) {}
+
+ /// analyzeFunction - Fill in the current structure with information gleaned
+ /// from the specified function.
+ void analyzeFunction(Function *F);
+ };
+
+ class VISIBILITY_HIDDEN SimpleInliner : public Inliner {
+ std::map<const Function*, FunctionInfo> CachedFunctionInfo;
+ std::set<const Function*> NeverInline; // Functions that are never inlined
+ public:
+ SimpleInliner() : Inliner(&ID) {}
+ static char ID; // Pass identification, replacement for typeid
+ int getInlineCost(CallSite CS);
+ virtual bool doInitialization(CallGraph &CG);
+ };
+ char SimpleInliner::ID = 0;
+ RegisterPass<SimpleInliner> X("inline", "Function Integration/Inlining");
+}
+
+Pass *llvm::createFunctionInliningPass() { return new SimpleInliner(); }
+
+// CountCodeReductionForConstant - Figure out an approximation for how many
+// instructions will be constant folded if the specified value is constant.
+//
+static unsigned CountCodeReductionForConstant(Value *V) {
+ unsigned Reduction = 0;
+ for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E; ++UI)
+ if (isa<BranchInst>(*UI))
+ Reduction += 40; // Eliminating a conditional branch is a big win
+ else if (SwitchInst *SI = dyn_cast<SwitchInst>(*UI))
+ // Eliminating a switch is a big win, proportional to the number of edges
+ // deleted.
+ Reduction += (SI->getNumSuccessors()-1) * 40;
+ else if (CallInst *CI = dyn_cast<CallInst>(*UI)) {
+ // Turning an indirect call into a direct call is a BIG win
+ Reduction += CI->getCalledValue() == V ? 500 : 0;
+ } else if (InvokeInst *II = dyn_cast<InvokeInst>(*UI)) {
+ // Turning an indirect call into a direct call is a BIG win
+ Reduction += II->getCalledValue() == V ? 500 : 0;
+ } else {
+ // Figure out if this instruction will be removed due to simple constant
+ // propagation.
+ Instruction &Inst = cast<Instruction>(**UI);
+ bool AllOperandsConstant = true;
+ for (unsigned i = 0, e = Inst.getNumOperands(); i != e; ++i)
+ if (!isa<Constant>(Inst.getOperand(i)) && Inst.getOperand(i) != V) {
+ AllOperandsConstant = false;
+ break;
+ }
+
+ if (AllOperandsConstant) {
+ // We will get to remove this instruction...
+ Reduction += 7;
+
+ // And any other instructions that use it which become constants
+ // themselves.
+ Reduction += CountCodeReductionForConstant(&Inst);
+ }
+ }
+
+ return Reduction;
+}
+
+// CountCodeReductionForAlloca - Figure out an approximation of how much smaller
+// the function will be if it is inlined into a context where an argument
+// becomes an alloca.
+//
+static unsigned CountCodeReductionForAlloca(Value *V) {
+ if (!isa<PointerType>(V->getType())) return 0; // Not a pointer
+ unsigned Reduction = 0;
+ for (Value::use_iterator UI = V->use_begin(), E = V->use_end(); UI != E;++UI){
+ Instruction *I = cast<Instruction>(*UI);
+ if (isa<LoadInst>(I) || isa<StoreInst>(I))
+ Reduction += 10;
+ else if (GetElementPtrInst *GEP = dyn_cast<GetElementPtrInst>(I)) {
+ // If the GEP has variable indices, we won't be able to do much with it.
+ for (Instruction::op_iterator I = GEP->op_begin()+1, E = GEP->op_end();
+ I != E; ++I)
+ if (!isa<Constant>(*I)) return 0;
+ Reduction += CountCodeReductionForAlloca(GEP)+15;
+ } else {
+ // If there is some other strange instruction, we're not going to be able
+ // to do much if we inline this.
+ return 0;
+ }
+ }
+
+ return Reduction;
+}
+
+/// analyzeFunction - Fill in the current structure with information gleaned
+/// from the specified function.
+void FunctionInfo::analyzeFunction(Function *F) {
+ unsigned NumInsts = 0, NumBlocks = 0;
+
+ // Look at the size of the callee. Each basic block counts as 20 units, and
+ // each instruction counts as 10.
+ for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
+ for (BasicBlock::const_iterator II = BB->begin(), E = BB->end();
+ II != E; ++II) {
+ if (isa<DbgInfoIntrinsic>(II)) continue; // Debug intrinsics don't count.
+
+ // Noop casts, including ptr <-> int, don't count.
+ if (const CastInst *CI = dyn_cast<CastInst>(II)) {
+ if (CI->isLosslessCast() || isa<IntToPtrInst>(CI) ||
+ isa<PtrToIntInst>(CI))
+ continue;
+ } else if (const GetElementPtrInst *GEPI =
+ dyn_cast<GetElementPtrInst>(II)) {
+ // If a GEP has all constant indices, it will probably be folded with
+ // a load/store.
+ bool AllConstant = true;
+ for (unsigned i = 1, e = GEPI->getNumOperands(); i != e; ++i)
+ if (!isa<ConstantInt>(GEPI->getOperand(i))) {
+ AllConstant = false;
+ break;
+ }
+ if (AllConstant) continue;
+ }
+
+ ++NumInsts;
+ }
+
+ ++NumBlocks;
+ }
+
+ this->NumBlocks = NumBlocks;
+ this->NumInsts = NumInsts;
+
+ // Check out all of the arguments to the function, figuring out how much
+ // code can be eliminated if one of the arguments is a constant.
+ for (Function::arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
+ ArgumentWeights.push_back(ArgInfo(CountCodeReductionForConstant(I),
+ CountCodeReductionForAlloca(I)));
+}
+
+
+// getInlineCost - The heuristic used to determine if we should inline the
+// function call or not.
+//
+int SimpleInliner::getInlineCost(CallSite CS) {
+ Instruction *TheCall = CS.getInstruction();
+ Function *Callee = CS.getCalledFunction();
+ const Function *Caller = TheCall->getParent()->getParent();
+
+ // Don't inline a directly recursive call.
+ if (Caller == Callee ||
+ // Don't inline functions which can be redefined at link-time to mean
+ // something else. link-once linkage is ok though.
+ Callee->hasWeakLinkage() ||
+
+ // Don't inline functions marked noinline.
+ NeverInline.count(Callee))
+ return 2000000000;
+
+ // InlineCost - This value measures how good of an inline candidate this call
+ // site is to inline. A lower inline cost make is more likely for the call to
+ // be inlined. This value may go negative.
+ //
+ int InlineCost = 0;
+
+ // If there is only one call of the function, and it has internal linkage,
+ // make it almost guaranteed to be inlined.
+ //
+ if (Callee->hasInternalLinkage() && Callee->hasOneUse())
+ InlineCost -= 30000;
+
+ // If this function uses the coldcc calling convention, prefer not to inline
+ // it.
+ if (Callee->getCallingConv() == CallingConv::Cold)
+ InlineCost += 2000;
+
+ // If the instruction after the call, or if the normal destination of the
+ // invoke is an unreachable instruction, the function is noreturn. As such,
+ // there is little point in inlining this.
+ if (InvokeInst *II = dyn_cast<InvokeInst>(TheCall)) {
+ if (isa<UnreachableInst>(II->getNormalDest()->begin()))
+ InlineCost += 10000;
+ } else if (isa<UnreachableInst>(++BasicBlock::iterator(TheCall)))
+ InlineCost += 10000;
+
+ // Get information about the callee...
+ FunctionInfo &CalleeFI = CachedFunctionInfo[Callee];
+
+ // If we haven't calculated this information yet, do so now.
+ if (CalleeFI.NumBlocks == 0)
+ CalleeFI.analyzeFunction(Callee);
+
+ // Add to the inline quality for properties that make the call valuable to
+ // inline. This includes factors that indicate that the result of inlining
+ // the function will be optimizable. Currently this just looks at arguments
+ // passed into the function.
+ //
+ unsigned ArgNo = 0;
+ for (CallSite::arg_iterator I = CS.arg_begin(), E = CS.arg_end();
+ I != E; ++I, ++ArgNo) {
+ // Each argument passed in has a cost at both the caller and the callee
+ // sides. This favors functions that take many arguments over functions
+ // that take few arguments.
+ InlineCost -= 20;
+
+ // If this is a function being passed in, it is very likely that we will be
+ // able to turn an indirect function call into a direct function call.
+ if (isa<Function>(I))
+ InlineCost -= 100;
+
+ // If an alloca is passed in, inlining this function is likely to allow
+ // significant future optimization possibilities (like scalar promotion, and
+ // scalarization), so encourage the inlining of the function.
+ //
+ else if (isa<AllocaInst>(I)) {
+ if (ArgNo < CalleeFI.ArgumentWeights.size())
+ InlineCost -= CalleeFI.ArgumentWeights[ArgNo].AllocaWeight;
+
+ // If this is a constant being passed into the function, use the argument
+ // weights calculated for the callee to determine how much will be folded
+ // away with this information.
+ } else if (isa<Constant>(I)) {
+ if (ArgNo < CalleeFI.ArgumentWeights.size())
+ InlineCost -= CalleeFI.ArgumentWeights[ArgNo].ConstantWeight;
+ }
+ }
+
+ // Now that we have considered all of the factors that make the call site more
+ // likely to be inlined, look at factors that make us not want to inline it.
+
+ // Don't inline into something too big, which would make it bigger. Here, we
+ // count each basic block as a single unit.
+ //
+ InlineCost += Caller->size()/20;
+
+
+ // Look at the size of the callee. Each basic block counts as 20 units, and
+ // each instruction counts as 5.
+ InlineCost += CalleeFI.NumInsts*5 + CalleeFI.NumBlocks*20;
+ return InlineCost;
+}
+
+// doInitialization - Initializes the vector of functions that have been
+// annotated with the noinline attribute.
+bool SimpleInliner::doInitialization(CallGraph &CG) {
+
+ Module &M = CG.getModule();
+
+ // Get llvm.noinline
+ GlobalVariable *GV = M.getNamedGlobal("llvm.noinline");
+
+ if (GV == 0)
+ return false;
+
+ const ConstantArray *InitList = dyn_cast<ConstantArray>(GV->getInitializer());
+
+ if (InitList == 0)
+ return false;
+
+ // Iterate over each element and add to the NeverInline set
+ for (unsigned i = 0, e = InitList->getNumOperands(); i != e; ++i) {
+
+ // Get Source
+ const Constant *Elt = InitList->getOperand(i);
+
+ if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(Elt))
+ if (CE->getOpcode() == Instruction::BitCast)
+ Elt = CE->getOperand(0);
+
+ // Insert into set of functions to never inline
+ if (const Function *F = dyn_cast<Function>(Elt))
+ NeverInline.insert(F);
+ }
+
+ return false;
+}
diff --git a/lib/Transforms/IPO/Inliner.cpp b/lib/Transforms/IPO/Inliner.cpp
new file mode 100644
index 0000000..85893d7
--- /dev/null
+++ b/lib/Transforms/IPO/Inliner.cpp
@@ -0,0 +1,217 @@
+//===- Inliner.cpp - Code common to all inliners --------------------------===//
+//
+// 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 implements the mechanics required to implement inlining without
+// missing any calls and updating the call graph. The decisions of which calls
+// are profitable to inline are implemented elsewhere.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "inline"
+#include "llvm/Module.h"
+#include "llvm/Instructions.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Transforms/IPO/InlinerPass.h"
+#include "llvm/Transforms/Utils/Cloning.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/Statistic.h"
+#include <set>
+using namespace llvm;
+
+STATISTIC(NumInlined, "Number of functions inlined");
+STATISTIC(NumDeleted, "Number of functions deleted because all callers found");
+
+namespace {
+ cl::opt<unsigned> // FIXME: 200 is VERY conservative
+ InlineLimit("inline-threshold", cl::Hidden, cl::init(200),
+ cl::desc("Control the amount of inlining to perform (default = 200)"));
+}
+
+Inliner::Inliner(const void *ID)
+ : CallGraphSCCPass((intptr_t)ID), InlineThreshold(InlineLimit) {}
+
+/// getAnalysisUsage - For this class, we declare that we require and preserve
+/// the call graph. If the derived class implements this method, it should
+/// always explicitly call the implementation here.
+void Inliner::getAnalysisUsage(AnalysisUsage &Info) const {
+ Info.addRequired<TargetData>();
+ CallGraphSCCPass::getAnalysisUsage(Info);
+}
+
+// InlineCallIfPossible - If it is possible to inline the specified call site,
+// do so and update the CallGraph for this operation.
+static bool InlineCallIfPossible(CallSite CS, CallGraph &CG,
+ const std::set<Function*> &SCCFunctions,
+ const TargetData &TD) {
+ Function *Callee = CS.getCalledFunction();
+ if (!InlineFunction(CS, &CG, &TD)) return false;
+
+ // If we inlined the last possible call site to the function, delete the
+ // function body now.
+ if (Callee->use_empty() && Callee->hasInternalLinkage() &&
+ !SCCFunctions.count(Callee)) {
+ DOUT << " -> Deleting dead function: " << Callee->getName() << "\n";
+
+ // Remove any call graph edges from the callee to its callees.
+ CallGraphNode *CalleeNode = CG[Callee];
+ while (CalleeNode->begin() != CalleeNode->end())
+ CalleeNode->removeCallEdgeTo((CalleeNode->end()-1)->second);
+
+ // Removing the node for callee from the call graph and delete it.
+ delete CG.removeFunctionFromModule(CalleeNode);
+ ++NumDeleted;
+ }
+ return true;
+}
+
+bool Inliner::runOnSCC(const std::vector<CallGraphNode*> &SCC) {
+ CallGraph &CG = getAnalysis<CallGraph>();
+
+ std::set<Function*> SCCFunctions;
+ DOUT << "Inliner visiting SCC:";
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
+ Function *F = SCC[i]->getFunction();
+ if (F) SCCFunctions.insert(F);
+ DOUT << " " << (F ? F->getName() : "INDIRECTNODE");
+ }
+
+ // Scan through and identify all call sites ahead of time so that we only
+ // inline call sites in the original functions, not call sites that result
+ // from inlining other functions.
+ std::vector<CallSite> CallSites;
+
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i)
+ if (Function *F = SCC[i]->getFunction())
+ for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+ for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ++I) {
+ CallSite CS = CallSite::get(I);
+ if (CS.getInstruction() && (!CS.getCalledFunction() ||
+ !CS.getCalledFunction()->isDeclaration()))
+ CallSites.push_back(CS);
+ }
+
+ DOUT << ": " << CallSites.size() << " call sites.\n";
+
+ // Now that we have all of the call sites, move the ones to functions in the
+ // current SCC to the end of the list.
+ unsigned FirstCallInSCC = CallSites.size();
+ for (unsigned i = 0; i < FirstCallInSCC; ++i)
+ if (Function *F = CallSites[i].getCalledFunction())
+ if (SCCFunctions.count(F))
+ std::swap(CallSites[i--], CallSites[--FirstCallInSCC]);
+
+ // Now that we have all of the call sites, loop over them and inline them if
+ // it looks profitable to do so.
+ bool Changed = false;
+ bool LocalChange;
+ do {
+ LocalChange = false;
+ // Iterate over the outer loop because inlining functions can cause indirect
+ // calls to become direct calls.
+ for (unsigned CSi = 0; CSi != CallSites.size(); ++CSi)
+ if (Function *Callee = CallSites[CSi].getCalledFunction()) {
+ // Calls to external functions are never inlinable.
+ if (Callee->isDeclaration() ||
+ CallSites[CSi].getInstruction()->getParent()->getParent() ==Callee){
+ if (SCC.size() == 1) {
+ std::swap(CallSites[CSi], CallSites.back());
+ CallSites.pop_back();
+ } else {
+ // Keep the 'in SCC / not in SCC' boundary correct.
+ CallSites.erase(CallSites.begin()+CSi);
+ }
+ --CSi;
+ continue;
+ }
+
+ // If the policy determines that we should inline this function,
+ // try to do so.
+ CallSite CS = CallSites[CSi];
+ int InlineCost = getInlineCost(CS);
+ if (InlineCost >= (int)InlineThreshold) {
+ DOUT << " NOT Inlining: cost=" << InlineCost
+ << ", Call: " << *CS.getInstruction();
+ } else {
+ DOUT << " Inlining: cost=" << InlineCost
+ << ", Call: " << *CS.getInstruction();
+
+ // Attempt to inline the function...
+ if (InlineCallIfPossible(CS, CG, SCCFunctions,
+ getAnalysis<TargetData>())) {
+ // Remove this call site from the list. If possible, use
+ // swap/pop_back for efficiency, but do not use it if doing so would
+ // move a call site to a function in this SCC before the
+ // 'FirstCallInSCC' barrier.
+ if (SCC.size() == 1) {
+ std::swap(CallSites[CSi], CallSites.back());
+ CallSites.pop_back();
+ } else {
+ CallSites.erase(CallSites.begin()+CSi);
+ }
+ --CSi;
+
+ ++NumInlined;
+ Changed = true;
+ LocalChange = true;
+ }
+ }
+ }
+ } while (LocalChange);
+
+ return Changed;
+}
+
+// doFinalization - Remove now-dead linkonce functions at the end of
+// processing to avoid breaking the SCC traversal.
+bool Inliner::doFinalization(CallGraph &CG) {
+ std::set<CallGraphNode*> FunctionsToRemove;
+
+ // Scan for all of the functions, looking for ones that should now be removed
+ // from the program. Insert the dead ones in the FunctionsToRemove set.
+ for (CallGraph::iterator I = CG.begin(), E = CG.end(); I != E; ++I) {
+ CallGraphNode *CGN = I->second;
+ if (Function *F = CGN ? CGN->getFunction() : 0) {
+ // If the only remaining users of the function are dead constants, remove
+ // them.
+ F->removeDeadConstantUsers();
+
+ if ((F->hasLinkOnceLinkage() || F->hasInternalLinkage()) &&
+ F->use_empty()) {
+
+ // Remove any call graph edges from the function to its callees.
+ while (CGN->begin() != CGN->end())
+ CGN->removeCallEdgeTo((CGN->end()-1)->second);
+
+ // Remove any edges from the external node to the function's call graph
+ // node. These edges might have been made irrelegant due to
+ // optimization of the program.
+ CG.getExternalCallingNode()->removeAnyCallEdgeTo(CGN);
+
+ // Removing the node for callee from the call graph and delete it.
+ FunctionsToRemove.insert(CGN);
+ }
+ }
+ }
+
+ // Now that we know which functions to delete, do so. We didn't want to do
+ // this inline, because that would invalidate our CallGraph::iterator
+ // objects. :(
+ bool Changed = false;
+ for (std::set<CallGraphNode*>::iterator I = FunctionsToRemove.begin(),
+ E = FunctionsToRemove.end(); I != E; ++I) {
+ delete CG.removeFunctionFromModule(*I);
+ ++NumDeleted;
+ Changed = true;
+ }
+
+ return Changed;
+}
diff --git a/lib/Transforms/IPO/Internalize.cpp b/lib/Transforms/IPO/Internalize.cpp
new file mode 100644
index 0000000..7b5392c
--- /dev/null
+++ b/lib/Transforms/IPO/Internalize.cpp
@@ -0,0 +1,154 @@
+//===-- Internalize.cpp - Mark functions internal -------------------------===//
+//
+// 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 pass loops over all of the functions in the input module, looking for a
+// main function. If a main function is found, all other functions and all
+// global variables with initializers are marked as internal.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "internalize"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Pass.h"
+#include "llvm/Module.h"
+#include "llvm/Support/CommandLine.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/ADT/Statistic.h"
+#include <fstream>
+#include <set>
+using namespace llvm;
+
+STATISTIC(NumFunctions, "Number of functions internalized");
+STATISTIC(NumGlobals , "Number of global vars internalized");
+
+namespace {
+
+ // APIFile - A file which contains a list of symbols that should not be marked
+ // external.
+ cl::opt<std::string>
+ APIFile("internalize-public-api-file", cl::value_desc("filename"),
+ cl::desc("A file containing list of symbol names to preserve"));
+
+ // APIList - A list of symbols that should not be marked internal.
+ cl::list<std::string>
+ APIList("internalize-public-api-list", cl::value_desc("list"),
+ cl::desc("A list of symbol names to preserve"),
+ cl::CommaSeparated);
+
+ class VISIBILITY_HIDDEN InternalizePass : public ModulePass {
+ std::set<std::string> ExternalNames;
+ bool DontInternalize;
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ InternalizePass(bool InternalizeEverything = true);
+ InternalizePass(const std::vector <const char *>& exportList);
+ void LoadFile(const char *Filename);
+ virtual bool runOnModule(Module &M);
+ };
+ char InternalizePass::ID = 0;
+ RegisterPass<InternalizePass> X("internalize", "Internalize Global Symbols");
+} // end anonymous namespace
+
+InternalizePass::InternalizePass(bool InternalizeEverything)
+ : ModulePass((intptr_t)&ID), DontInternalize(false){
+ if (!APIFile.empty()) // If a filename is specified, use it
+ LoadFile(APIFile.c_str());
+ else if (!APIList.empty()) // Else, if a list is specified, use it.
+ ExternalNames.insert(APIList.begin(), APIList.end());
+ else if (!InternalizeEverything)
+ // Finally, if we're allowed to, internalize all but main.
+ DontInternalize = true;
+}
+
+InternalizePass::InternalizePass(const std::vector<const char *>&exportList)
+ : ModulePass((intptr_t)&ID), DontInternalize(false){
+ for(std::vector<const char *>::const_iterator itr = exportList.begin();
+ itr != exportList.end(); itr++) {
+ ExternalNames.insert(*itr);
+ }
+}
+
+void InternalizePass::LoadFile(const char *Filename) {
+ // Load the APIFile...
+ std::ifstream In(Filename);
+ if (!In.good()) {
+ cerr << "WARNING: Internalize couldn't load file '" << Filename << "'!\n";
+ return; // Do not internalize anything...
+ }
+ while (In) {
+ std::string Symbol;
+ In >> Symbol;
+ if (!Symbol.empty())
+ ExternalNames.insert(Symbol);
+ }
+}
+
+bool InternalizePass::runOnModule(Module &M) {
+ if (DontInternalize) return false;
+
+ // If no list or file of symbols was specified, check to see if there is a
+ // "main" symbol defined in the module. If so, use it, otherwise do not
+ // internalize the module, it must be a library or something.
+ //
+ if (ExternalNames.empty()) {
+ Function *MainFunc = M.getFunction("main");
+ if (MainFunc == 0 || MainFunc->isDeclaration())
+ return false; // No main found, must be a library...
+
+ // Preserve main, internalize all else.
+ ExternalNames.insert(MainFunc->getName());
+ }
+
+ bool Changed = false;
+
+ // Found a main function, mark all functions not named main as internal.
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I)
+ if (!I->isDeclaration() && // Function must be defined here
+ !I->hasInternalLinkage() && // Can't already have internal linkage
+ !ExternalNames.count(I->getName())) {// Not marked to keep external?
+ I->setLinkage(GlobalValue::InternalLinkage);
+ Changed = true;
+ ++NumFunctions;
+ DOUT << "Internalizing func " << I->getName() << "\n";
+ }
+
+ // Never internalize the llvm.used symbol. It is used to implement
+ // attribute((used)).
+ ExternalNames.insert("llvm.used");
+
+ // Never internalize anchors used by the machine module info, else the info
+ // won't find them. (see MachineModuleInfo.)
+ ExternalNames.insert("llvm.dbg.compile_units");
+ ExternalNames.insert("llvm.dbg.global_variables");
+ ExternalNames.insert("llvm.dbg.subprograms");
+ ExternalNames.insert("llvm.global_ctors");
+ ExternalNames.insert("llvm.global_dtors");
+
+ // Mark all global variables with initializers as internal as well.
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
+ if (!I->isDeclaration() && !I->hasInternalLinkage() &&
+ !ExternalNames.count(I->getName())) {
+ I->setLinkage(GlobalValue::InternalLinkage);
+ Changed = true;
+ ++NumGlobals;
+ DOUT << "Internalized gvar " << I->getName() << "\n";
+ }
+
+ return Changed;
+}
+
+ModulePass *llvm::createInternalizePass(bool InternalizeEverything) {
+ return new InternalizePass(InternalizeEverything);
+}
+
+ModulePass *llvm::createInternalizePass(const std::vector <const char *> &el) {
+ return new InternalizePass(el);
+}
diff --git a/lib/Transforms/IPO/LoopExtractor.cpp b/lib/Transforms/IPO/LoopExtractor.cpp
new file mode 100644
index 0000000..7b14ce0
--- /dev/null
+++ b/lib/Transforms/IPO/LoopExtractor.cpp
@@ -0,0 +1,201 @@
+//===- LoopExtractor.cpp - Extract each loop into a new function ----------===//
+//
+// 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.
+//
+//===----------------------------------------------------------------------===//
+//
+// A pass wrapper around the ExtractLoop() scalar transformation to extract each
+// top-level loop into its own new function. If the loop is the ONLY loop in a
+// given function, it is not touched. This is a pass most useful for debugging
+// via bugpoint.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "loop-extract"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Analysis/Dominators.h"
+#include "llvm/Analysis/LoopInfo.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Transforms/Scalar.h"
+#include "llvm/Transforms/Utils/FunctionUtils.h"
+#include "llvm/ADT/Statistic.h"
+using namespace llvm;
+
+STATISTIC(NumExtracted, "Number of loops extracted");
+
+namespace {
+ // FIXME: This is not a function pass, but the PassManager doesn't allow
+ // Module passes to require FunctionPasses, so we can't get loop info if we're
+ // not a function pass.
+ struct VISIBILITY_HIDDEN LoopExtractor : public FunctionPass {
+ static char ID; // Pass identification, replacement for typeid
+ unsigned NumLoops;
+
+ LoopExtractor(unsigned numLoops = ~0)
+ : FunctionPass((intptr_t)&ID), NumLoops(numLoops) {}
+
+ virtual bool runOnFunction(Function &F);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.addRequiredID(BreakCriticalEdgesID);
+ AU.addRequiredID(LoopSimplifyID);
+ AU.addRequired<DominatorTree>();
+ AU.addRequired<LoopInfo>();
+ }
+ };
+
+ char LoopExtractor::ID = 0;
+ RegisterPass<LoopExtractor>
+ X("loop-extract", "Extract loops into new functions");
+
+ /// SingleLoopExtractor - For bugpoint.
+ struct SingleLoopExtractor : public LoopExtractor {
+ static char ID; // Pass identification, replacement for typeid
+ SingleLoopExtractor() : LoopExtractor(1) {}
+ };
+
+ char SingleLoopExtractor::ID = 0;
+ RegisterPass<SingleLoopExtractor>
+ Y("loop-extract-single", "Extract at most one loop into a new function");
+} // End anonymous namespace
+
+// createLoopExtractorPass - This pass extracts all natural loops from the
+// program into a function if it can.
+//
+FunctionPass *llvm::createLoopExtractorPass() { return new LoopExtractor(); }
+
+bool LoopExtractor::runOnFunction(Function &F) {
+ LoopInfo &LI = getAnalysis<LoopInfo>();
+
+ // If this function has no loops, there is nothing to do.
+ if (LI.begin() == LI.end())
+ return false;
+
+ DominatorTree &DT = getAnalysis<DominatorTree>();
+
+ // If there is more than one top-level loop in this function, extract all of
+ // the loops.
+ bool Changed = false;
+ if (LI.end()-LI.begin() > 1) {
+ for (LoopInfo::iterator i = LI.begin(), e = LI.end(); i != e; ++i) {
+ if (NumLoops == 0) return Changed;
+ --NumLoops;
+ Changed |= ExtractLoop(DT, *i) != 0;
+ ++NumExtracted;
+ }
+ } else {
+ // Otherwise there is exactly one top-level loop. If this function is more
+ // than a minimal wrapper around the loop, extract the loop.
+ Loop *TLL = *LI.begin();
+ bool ShouldExtractLoop = false;
+
+ // Extract the loop if the entry block doesn't branch to the loop header.
+ TerminatorInst *EntryTI = F.getEntryBlock().getTerminator();
+ if (!isa<BranchInst>(EntryTI) ||
+ !cast<BranchInst>(EntryTI)->isUnconditional() ||
+ EntryTI->getSuccessor(0) != TLL->getHeader())
+ ShouldExtractLoop = true;
+ else {
+ // Check to see if any exits from the loop are more than just return
+ // blocks.
+ std::vector<BasicBlock*> ExitBlocks;
+ TLL->getExitBlocks(ExitBlocks);
+ for (unsigned i = 0, e = ExitBlocks.size(); i != e; ++i)
+ if (!isa<ReturnInst>(ExitBlocks[i]->getTerminator())) {
+ ShouldExtractLoop = true;
+ break;
+ }
+ }
+
+ if (ShouldExtractLoop) {
+ if (NumLoops == 0) return Changed;
+ --NumLoops;
+ Changed |= ExtractLoop(DT, TLL) != 0;
+ ++NumExtracted;
+ } else {
+ // Okay, this function is a minimal container around the specified loop.
+ // If we extract the loop, we will continue to just keep extracting it
+ // infinitely... so don't extract it. However, if the loop contains any
+ // subloops, extract them.
+ for (Loop::iterator i = TLL->begin(), e = TLL->end(); i != e; ++i) {
+ if (NumLoops == 0) return Changed;
+ --NumLoops;
+ Changed |= ExtractLoop(DT, *i) != 0;
+ ++NumExtracted;
+ }
+ }
+ }
+
+ return Changed;
+}
+
+// createSingleLoopExtractorPass - This pass extracts one natural loop from the
+// program into a function if it can. This is used by bugpoint.
+//
+FunctionPass *llvm::createSingleLoopExtractorPass() {
+ return new SingleLoopExtractor();
+}
+
+
+namespace {
+ /// BlockExtractorPass - This pass is used by bugpoint to extract all blocks
+ /// from the module into their own functions except for those specified by the
+ /// BlocksToNotExtract list.
+ class BlockExtractorPass : public ModulePass {
+ std::vector<BasicBlock*> BlocksToNotExtract;
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ BlockExtractorPass(std::vector<BasicBlock*> &B)
+ : ModulePass((intptr_t)&ID), BlocksToNotExtract(B) {}
+ BlockExtractorPass() : ModulePass((intptr_t)&ID) {}
+
+ bool runOnModule(Module &M);
+ };
+
+ char BlockExtractorPass::ID = 0;
+ RegisterPass<BlockExtractorPass>
+ XX("extract-blocks", "Extract Basic Blocks From Module (for bugpoint use)");
+}
+
+// createBlockExtractorPass - This pass extracts all blocks (except those
+// specified in the argument list) from the functions in the module.
+//
+ModulePass *llvm::createBlockExtractorPass(std::vector<BasicBlock*> &BTNE) {
+ return new BlockExtractorPass(BTNE);
+}
+
+bool BlockExtractorPass::runOnModule(Module &M) {
+ std::set<BasicBlock*> TranslatedBlocksToNotExtract;
+ for (unsigned i = 0, e = BlocksToNotExtract.size(); i != e; ++i) {
+ BasicBlock *BB = BlocksToNotExtract[i];
+ Function *F = BB->getParent();
+
+ // Map the corresponding function in this module.
+ Function *MF = M.getFunction(F->getName());
+ assert(MF->getFunctionType() == F->getFunctionType() && "Wrong function?");
+
+ // Figure out which index the basic block is in its function.
+ Function::iterator BBI = MF->begin();
+ std::advance(BBI, std::distance(F->begin(), Function::iterator(BB)));
+ TranslatedBlocksToNotExtract.insert(BBI);
+ }
+
+ // Now that we know which blocks to not extract, figure out which ones we WANT
+ // to extract.
+ std::vector<BasicBlock*> BlocksToExtract;
+ for (Module::iterator F = M.begin(), E = M.end(); F != E; ++F)
+ for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
+ if (!TranslatedBlocksToNotExtract.count(BB))
+ BlocksToExtract.push_back(BB);
+
+ for (unsigned i = 0, e = BlocksToExtract.size(); i != e; ++i)
+ ExtractBasicBlock(BlocksToExtract[i]);
+
+ return !BlocksToExtract.empty();
+}
diff --git a/lib/Transforms/IPO/LowerSetJmp.cpp b/lib/Transforms/IPO/LowerSetJmp.cpp
new file mode 100644
index 0000000..0243980
--- /dev/null
+++ b/lib/Transforms/IPO/LowerSetJmp.cpp
@@ -0,0 +1,534 @@
+//===- LowerSetJmp.cpp - Code pertaining to lowering set/long jumps -------===//
+//
+// 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 implements the lowering of setjmp and longjmp to use the
+// LLVM invoke and unwind instructions as necessary.
+//
+// Lowering of longjmp is fairly trivial. We replace the call with a
+// call to the LLVM library function "__llvm_sjljeh_throw_longjmp()".
+// This unwinds the stack for us calling all of the destructors for
+// objects allocated on the stack.
+//
+// At a setjmp call, the basic block is split and the setjmp removed.
+// The calls in a function that have a setjmp are converted to invoke
+// where the except part checks to see if it's a longjmp exception and,
+// if so, if it's handled in the function. If it is, then it gets the
+// value returned by the longjmp and goes to where the basic block was
+// split. Invoke instructions are handled in a similar fashion with the
+// original except block being executed if it isn't a longjmp except
+// that is handled by that function.
+//
+//===----------------------------------------------------------------------===//
+
+//===----------------------------------------------------------------------===//
+// FIXME: This pass doesn't deal with PHI statements just yet. That is,
+// we expect this to occur before SSAification is done. This would seem
+// to make sense, but in general, it might be a good idea to make this
+// pass invokable via the "opt" command at will.
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "lowersetjmp"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/InstVisitor.h"
+#include "llvm/Transforms/Utils/Local.h"
+#include "llvm/ADT/DepthFirstIterator.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/ADT/StringExtras.h"
+#include "llvm/ADT/VectorExtras.h"
+using namespace llvm;
+
+STATISTIC(LongJmpsTransformed, "Number of longjmps transformed");
+STATISTIC(SetJmpsTransformed , "Number of setjmps transformed");
+STATISTIC(CallsTransformed , "Number of calls invokified");
+STATISTIC(InvokesTransformed , "Number of invokes modified");
+
+namespace {
+ //===--------------------------------------------------------------------===//
+ // LowerSetJmp pass implementation.
+ class VISIBILITY_HIDDEN LowerSetJmp : public ModulePass,
+ public InstVisitor<LowerSetJmp> {
+ // LLVM library functions...
+ Constant *InitSJMap; // __llvm_sjljeh_init_setjmpmap
+ Constant *DestroySJMap; // __llvm_sjljeh_destroy_setjmpmap
+ Constant *AddSJToMap; // __llvm_sjljeh_add_setjmp_to_map
+ Constant *ThrowLongJmp; // __llvm_sjljeh_throw_longjmp
+ Constant *TryCatchLJ; // __llvm_sjljeh_try_catching_longjmp_exception
+ Constant *IsLJException; // __llvm_sjljeh_is_longjmp_exception
+ Constant *GetLJValue; // __llvm_sjljeh_get_longjmp_value
+
+ typedef std::pair<SwitchInst*, CallInst*> SwitchValuePair;
+
+ // Keep track of those basic blocks reachable via a depth-first search of
+ // the CFG from a setjmp call. We only need to transform those "call" and
+ // "invoke" instructions that are reachable from the setjmp call site.
+ std::set<BasicBlock*> DFSBlocks;
+
+ // The setjmp map is going to hold information about which setjmps
+ // were called (each setjmp gets its own number) and with which
+ // buffer it was called.
+ std::map<Function*, AllocaInst*> SJMap;
+
+ // The rethrow basic block map holds the basic block to branch to if
+ // the exception isn't handled in the current function and needs to
+ // be rethrown.
+ std::map<const Function*, BasicBlock*> RethrowBBMap;
+
+ // The preliminary basic block map holds a basic block that grabs the
+ // exception and determines if it's handled by the current function.
+ std::map<const Function*, BasicBlock*> PrelimBBMap;
+
+ // The switch/value map holds a switch inst/call inst pair. The
+ // switch inst controls which handler (if any) gets called and the
+ // value is the value returned to that handler by the call to
+ // __llvm_sjljeh_get_longjmp_value.
+ std::map<const Function*, SwitchValuePair> SwitchValMap;
+
+ // A map of which setjmps we've seen so far in a function.
+ std::map<const Function*, unsigned> SetJmpIDMap;
+
+ AllocaInst* GetSetJmpMap(Function* Func);
+ BasicBlock* GetRethrowBB(Function* Func);
+ SwitchValuePair GetSJSwitch(Function* Func, BasicBlock* Rethrow);
+
+ void TransformLongJmpCall(CallInst* Inst);
+ void TransformSetJmpCall(CallInst* Inst);
+
+ bool IsTransformableFunction(const std::string& Name);
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ LowerSetJmp() : ModulePass((intptr_t)&ID) {}
+
+ void visitCallInst(CallInst& CI);
+ void visitInvokeInst(InvokeInst& II);
+ void visitReturnInst(ReturnInst& RI);
+ void visitUnwindInst(UnwindInst& UI);
+
+ bool runOnModule(Module& M);
+ bool doInitialization(Module& M);
+ };
+
+ char LowerSetJmp::ID = 0;
+ RegisterPass<LowerSetJmp> X("lowersetjmp", "Lower Set Jump");
+} // end anonymous namespace
+
+// run - Run the transformation on the program. We grab the function
+// prototypes for longjmp and setjmp. If they are used in the program,
+// then we can go directly to the places they're at and transform them.
+bool LowerSetJmp::runOnModule(Module& M) {
+ bool Changed = false;
+
+ // These are what the functions are called.
+ Function* SetJmp = M.getFunction("llvm.setjmp");
+ Function* LongJmp = M.getFunction("llvm.longjmp");
+
+ // This program doesn't have longjmp and setjmp calls.
+ if ((!LongJmp || LongJmp->use_empty()) &&
+ (!SetJmp || SetJmp->use_empty())) return false;
+
+ // Initialize some values and functions we'll need to transform the
+ // setjmp/longjmp functions.
+ doInitialization(M);
+
+ if (SetJmp) {
+ for (Value::use_iterator B = SetJmp->use_begin(), E = SetJmp->use_end();
+ B != E; ++B) {
+ BasicBlock* BB = cast<Instruction>(*B)->getParent();
+ for (df_ext_iterator<BasicBlock*> I = df_ext_begin(BB, DFSBlocks),
+ E = df_ext_end(BB, DFSBlocks); I != E; ++I)
+ /* empty */;
+ }
+
+ while (!SetJmp->use_empty()) {
+ assert(isa<CallInst>(SetJmp->use_back()) &&
+ "User of setjmp intrinsic not a call?");
+ TransformSetJmpCall(cast<CallInst>(SetJmp->use_back()));
+ Changed = true;
+ }
+ }
+
+ if (LongJmp)
+ while (!LongJmp->use_empty()) {
+ assert(isa<CallInst>(LongJmp->use_back()) &&
+ "User of longjmp intrinsic not a call?");
+ TransformLongJmpCall(cast<CallInst>(LongJmp->use_back()));
+ Changed = true;
+ }
+
+ // Now go through the affected functions and convert calls and invokes
+ // to new invokes...
+ for (std::map<Function*, AllocaInst*>::iterator
+ B = SJMap.begin(), E = SJMap.end(); B != E; ++B) {
+ Function* F = B->first;
+ for (Function::iterator BB = F->begin(), BE = F->end(); BB != BE; ++BB)
+ for (BasicBlock::iterator IB = BB->begin(), IE = BB->end(); IB != IE; ) {
+ visit(*IB++);
+ if (IB != BB->end() && IB->getParent() != BB)
+ break; // The next instruction got moved to a different block!
+ }
+ }
+
+ DFSBlocks.clear();
+ SJMap.clear();
+ RethrowBBMap.clear();
+ PrelimBBMap.clear();
+ SwitchValMap.clear();
+ SetJmpIDMap.clear();
+
+ return Changed;
+}
+
+// doInitialization - For the lower long/setjmp pass, this ensures that a
+// module contains a declaration for the intrisic functions we are going
+// to call to convert longjmp and setjmp calls.
+//
+// This function is always successful, unless it isn't.
+bool LowerSetJmp::doInitialization(Module& M)
+{
+ const Type *SBPTy = PointerType::get(Type::Int8Ty);
+ const Type *SBPPTy = PointerType::get(SBPTy);
+
+ // N.B. See llvm/runtime/GCCLibraries/libexception/SJLJ-Exception.h for
+ // a description of the following library functions.
+
+ // void __llvm_sjljeh_init_setjmpmap(void**)
+ InitSJMap = M.getOrInsertFunction("__llvm_sjljeh_init_setjmpmap",
+ Type::VoidTy, SBPPTy, (Type *)0);
+ // void __llvm_sjljeh_destroy_setjmpmap(void**)
+ DestroySJMap = M.getOrInsertFunction("__llvm_sjljeh_destroy_setjmpmap",
+ Type::VoidTy, SBPPTy, (Type *)0);
+
+ // void __llvm_sjljeh_add_setjmp_to_map(void**, void*, unsigned)
+ AddSJToMap = M.getOrInsertFunction("__llvm_sjljeh_add_setjmp_to_map",
+ Type::VoidTy, SBPPTy, SBPTy,
+ Type::Int32Ty, (Type *)0);
+
+ // void __llvm_sjljeh_throw_longjmp(int*, int)
+ ThrowLongJmp = M.getOrInsertFunction("__llvm_sjljeh_throw_longjmp",
+ Type::VoidTy, SBPTy, Type::Int32Ty,
+ (Type *)0);
+
+ // unsigned __llvm_sjljeh_try_catching_longjmp_exception(void **)
+ TryCatchLJ =
+ M.getOrInsertFunction("__llvm_sjljeh_try_catching_longjmp_exception",
+ Type::Int32Ty, SBPPTy, (Type *)0);
+
+ // bool __llvm_sjljeh_is_longjmp_exception()
+ IsLJException = M.getOrInsertFunction("__llvm_sjljeh_is_longjmp_exception",
+ Type::Int1Ty, (Type *)0);
+
+ // int __llvm_sjljeh_get_longjmp_value()
+ GetLJValue = M.getOrInsertFunction("__llvm_sjljeh_get_longjmp_value",
+ Type::Int32Ty, (Type *)0);
+ return true;
+}
+
+// IsTransformableFunction - Return true if the function name isn't one
+// of the ones we don't want transformed. Currently, don't transform any
+// "llvm.{setjmp,longjmp}" functions and none of the setjmp/longjmp error
+// handling functions (beginning with __llvm_sjljeh_...they don't throw
+// exceptions).
+bool LowerSetJmp::IsTransformableFunction(const std::string& Name) {
+ std::string SJLJEh("__llvm_sjljeh");
+
+ if (Name.size() > SJLJEh.size())
+ return std::string(Name.begin(), Name.begin() + SJLJEh.size()) != SJLJEh;
+
+ return true;
+}
+
+// TransformLongJmpCall - Transform a longjmp call into a call to the
+// internal __llvm_sjljeh_throw_longjmp function. It then takes care of
+// throwing the exception for us.
+void LowerSetJmp::TransformLongJmpCall(CallInst* Inst)
+{
+ const Type* SBPTy = PointerType::get(Type::Int8Ty);
+
+ // Create the call to "__llvm_sjljeh_throw_longjmp". This takes the
+ // same parameters as "longjmp", except that the buffer is cast to a
+ // char*. It returns "void", so it doesn't need to replace any of
+ // Inst's uses and doesn't get a name.
+ CastInst* CI =
+ new BitCastInst(Inst->getOperand(1), SBPTy, "LJBuf", Inst);
+ new CallInst(ThrowLongJmp, CI, Inst->getOperand(2), "", Inst);
+
+ SwitchValuePair& SVP = SwitchValMap[Inst->getParent()->getParent()];
+
+ // If the function has a setjmp call in it (they are transformed first)
+ // we should branch to the basic block that determines if this longjmp
+ // is applicable here. Otherwise, issue an unwind.
+ if (SVP.first)
+ new BranchInst(SVP.first->getParent(), Inst);
+ else
+ new UnwindInst(Inst);
+
+ // Remove all insts after the branch/unwind inst. Go from back to front to
+ // avoid replaceAllUsesWith if possible.
+ BasicBlock *BB = Inst->getParent();
+ Instruction *Removed;
+ do {
+ Removed = &BB->back();
+ // If the removed instructions have any users, replace them now.
+ if (!Removed->use_empty())
+ Removed->replaceAllUsesWith(UndefValue::get(Removed->getType()));
+ Removed->eraseFromParent();
+ } while (Removed != Inst);
+
+ ++LongJmpsTransformed;
+}
+
+// GetSetJmpMap - Retrieve (create and initialize, if necessary) the
+// setjmp map. This map is going to hold information about which setjmps
+// were called (each setjmp gets its own number) and with which buffer it
+// was called. There can be only one!
+AllocaInst* LowerSetJmp::GetSetJmpMap(Function* Func)
+{
+ if (SJMap[Func]) return SJMap[Func];
+
+ // Insert the setjmp map initialization before the first instruction in
+ // the function.
+ Instruction* Inst = Func->getEntryBlock().begin();
+ assert(Inst && "Couldn't find even ONE instruction in entry block!");
+
+ // Fill in the alloca and call to initialize the SJ map.
+ const Type *SBPTy = PointerType::get(Type::Int8Ty);
+ AllocaInst* Map = new AllocaInst(SBPTy, 0, "SJMap", Inst);
+ new CallInst(InitSJMap, Map, "", Inst);
+ return SJMap[Func] = Map;
+}
+
+// GetRethrowBB - Only one rethrow basic block is needed per function.
+// If this is a longjmp exception but not handled in this block, this BB
+// performs the rethrow.
+BasicBlock* LowerSetJmp::GetRethrowBB(Function* Func)
+{
+ if (RethrowBBMap[Func]) return RethrowBBMap[Func];
+
+ // The basic block we're going to jump to if we need to rethrow the
+ // exception.
+ BasicBlock* Rethrow = new BasicBlock("RethrowExcept", Func);
+
+ // Fill in the "Rethrow" BB with a call to rethrow the exception. This
+ // is the last instruction in the BB since at this point the runtime
+ // should exit this function and go to the next function.
+ new UnwindInst(Rethrow);
+ return RethrowBBMap[Func] = Rethrow;
+}
+
+// GetSJSwitch - Return the switch statement that controls which handler
+// (if any) gets called and the value returned to that handler.
+LowerSetJmp::SwitchValuePair LowerSetJmp::GetSJSwitch(Function* Func,
+ BasicBlock* Rethrow)
+{
+ if (SwitchValMap[Func].first) return SwitchValMap[Func];
+
+ BasicBlock* LongJmpPre = new BasicBlock("LongJmpBlkPre", Func);
+ BasicBlock::InstListType& LongJmpPreIL = LongJmpPre->getInstList();
+
+ // Keep track of the preliminary basic block for some of the other
+ // transformations.
+ PrelimBBMap[Func] = LongJmpPre;
+
+ // Grab the exception.
+ CallInst* Cond = new CallInst(IsLJException, "IsLJExcept");
+ LongJmpPreIL.push_back(Cond);
+
+ // The "decision basic block" gets the number associated with the
+ // setjmp call returning to switch on and the value returned by
+ // longjmp.
+ BasicBlock* DecisionBB = new BasicBlock("LJDecisionBB", Func);
+ BasicBlock::InstListType& DecisionBBIL = DecisionBB->getInstList();
+
+ new BranchInst(DecisionBB, Rethrow, Cond, LongJmpPre);
+
+ // Fill in the "decision" basic block.
+ CallInst* LJVal = new CallInst(GetLJValue, "LJVal");
+ DecisionBBIL.push_back(LJVal);
+ CallInst* SJNum = new CallInst(TryCatchLJ, GetSetJmpMap(Func), "SJNum");
+ DecisionBBIL.push_back(SJNum);
+
+ SwitchInst* SI = new SwitchInst(SJNum, Rethrow, 0, DecisionBB);
+ return SwitchValMap[Func] = SwitchValuePair(SI, LJVal);
+}
+
+// TransformSetJmpCall - The setjmp call is a bit trickier to transform.
+// We're going to convert all setjmp calls to nops. Then all "call" and
+// "invoke" instructions in the function are converted to "invoke" where
+// the "except" branch is used when returning from a longjmp call.
+void LowerSetJmp::TransformSetJmpCall(CallInst* Inst)
+{
+ BasicBlock* ABlock = Inst->getParent();
+ Function* Func = ABlock->getParent();
+
+ // Add this setjmp to the setjmp map.
+ const Type* SBPTy = PointerType::get(Type::Int8Ty);
+ CastInst* BufPtr =
+ new BitCastInst(Inst->getOperand(1), SBPTy, "SBJmpBuf", Inst);
+ std::vector<Value*> Args =
+ make_vector<Value*>(GetSetJmpMap(Func), BufPtr,
+ ConstantInt::get(Type::Int32Ty,
+ SetJmpIDMap[Func]++), 0);
+ new CallInst(AddSJToMap, &Args[0], Args.size(), "", Inst);
+
+ // We are guaranteed that there are no values live across basic blocks
+ // (because we are "not in SSA form" yet), but there can still be values live
+ // in basic blocks. Because of this, splitting the setjmp block can cause
+ // values above the setjmp to not dominate uses which are after the setjmp
+ // call. For all of these occasions, we must spill the value to the stack.
+ //
+ std::set<Instruction*> InstrsAfterCall;
+
+ // The call is probably very close to the end of the basic block, for the
+ // common usage pattern of: 'if (setjmp(...))', so keep track of the
+ // instructions after the call.
+ for (BasicBlock::iterator I = ++BasicBlock::iterator(Inst), E = ABlock->end();
+ I != E; ++I)
+ InstrsAfterCall.insert(I);
+
+ for (BasicBlock::iterator II = ABlock->begin();
+ II != BasicBlock::iterator(Inst); ++II)
+ // Loop over all of the uses of instruction. If any of them are after the
+ // call, "spill" the value to the stack.
+ for (Value::use_iterator UI = II->use_begin(), E = II->use_end();
+ UI != E; ++UI)
+ if (cast<Instruction>(*UI)->getParent() != ABlock ||
+ InstrsAfterCall.count(cast<Instruction>(*UI))) {
+ DemoteRegToStack(*II);
+ break;
+ }
+ InstrsAfterCall.clear();
+
+ // Change the setjmp call into a branch statement. We'll remove the
+ // setjmp call in a little bit. No worries.
+ BasicBlock* SetJmpContBlock = ABlock->splitBasicBlock(Inst);
+ assert(SetJmpContBlock && "Couldn't split setjmp BB!!");
+
+ SetJmpContBlock->setName(ABlock->getName()+"SetJmpCont");
+
+ // Add the SetJmpContBlock to the set of blocks reachable from a setjmp.
+ DFSBlocks.insert(SetJmpContBlock);
+
+ // This PHI node will be in the new block created from the
+ // splitBasicBlock call.
+ PHINode* PHI = new PHINode(Type::Int32Ty, "SetJmpReturn", Inst);
+
+ // Coming from a call to setjmp, the return is 0.
+ PHI->addIncoming(ConstantInt::getNullValue(Type::Int32Ty), ABlock);
+
+ // Add the case for this setjmp's number...
+ SwitchValuePair SVP = GetSJSwitch(Func, GetRethrowBB(Func));
+ SVP.first->addCase(ConstantInt::get(Type::Int32Ty, SetJmpIDMap[Func] - 1),
+ SetJmpContBlock);
+
+ // Value coming from the handling of the exception.
+ PHI->addIncoming(SVP.second, SVP.second->getParent());
+
+ // Replace all uses of this instruction with the PHI node created by
+ // the eradication of setjmp.
+ Inst->replaceAllUsesWith(PHI);
+ Inst->getParent()->getInstList().erase(Inst);
+
+ ++SetJmpsTransformed;
+}
+
+// visitCallInst - This converts all LLVM call instructions into invoke
+// instructions. The except part of the invoke goes to the "LongJmpBlkPre"
+// that grabs the exception and proceeds to determine if it's a longjmp
+// exception or not.
+void LowerSetJmp::visitCallInst(CallInst& CI)
+{
+ if (CI.getCalledFunction())
+ if (!IsTransformableFunction(CI.getCalledFunction()->getName()) ||
+ CI.getCalledFunction()->isIntrinsic()) return;
+
+ BasicBlock* OldBB = CI.getParent();
+
+ // If not reachable from a setjmp call, don't transform.
+ if (!DFSBlocks.count(OldBB)) return;
+
+ BasicBlock* NewBB = OldBB->splitBasicBlock(CI);
+ assert(NewBB && "Couldn't split BB of \"call\" instruction!!");
+ DFSBlocks.insert(NewBB);
+ NewBB->setName("Call2Invoke");
+
+ Function* Func = OldBB->getParent();
+
+ // Construct the new "invoke" instruction.
+ TerminatorInst* Term = OldBB->getTerminator();
+ std::vector<Value*> Params(CI.op_begin() + 1, CI.op_end());
+ InvokeInst* II = new
+ InvokeInst(CI.getCalledValue(), NewBB, PrelimBBMap[Func],
+ &Params[0], Params.size(), CI.getName(), Term);
+
+ // Replace the old call inst with the invoke inst and remove the call.
+ CI.replaceAllUsesWith(II);
+ CI.getParent()->getInstList().erase(&CI);
+
+ // The old terminator is useless now that we have the invoke inst.
+ Term->getParent()->getInstList().erase(Term);
+ ++CallsTransformed;
+}
+
+// visitInvokeInst - Converting the "invoke" instruction is fairly
+// straight-forward. The old exception part is replaced by a query asking
+// if this is a longjmp exception. If it is, then it goes to the longjmp
+// exception blocks. Otherwise, control is passed the old exception.
+void LowerSetJmp::visitInvokeInst(InvokeInst& II)
+{
+ if (II.getCalledFunction())
+ if (!IsTransformableFunction(II.getCalledFunction()->getName()) ||
+ II.getCalledFunction()->isIntrinsic()) return;
+
+ BasicBlock* BB = II.getParent();
+
+ // If not reachable from a setjmp call, don't transform.
+ if (!DFSBlocks.count(BB)) return;
+
+ BasicBlock* ExceptBB = II.getUnwindDest();
+
+ Function* Func = BB->getParent();
+ BasicBlock* NewExceptBB = new BasicBlock("InvokeExcept", Func);
+ BasicBlock::InstListType& InstList = NewExceptBB->getInstList();
+
+ // If this is a longjmp exception, then branch to the preliminary BB of
+ // the longjmp exception handling. Otherwise, go to the old exception.
+ CallInst* IsLJExcept = new CallInst(IsLJException, "IsLJExcept");
+ InstList.push_back(IsLJExcept);
+
+ new BranchInst(PrelimBBMap[Func], ExceptBB, IsLJExcept, NewExceptBB);
+
+ II.setUnwindDest(NewExceptBB);
+ ++InvokesTransformed;
+}
+
+// visitReturnInst - We want to destroy the setjmp map upon exit from the
+// function.
+void LowerSetJmp::visitReturnInst(ReturnInst &RI) {
+ Function* Func = RI.getParent()->getParent();
+ new CallInst(DestroySJMap, GetSetJmpMap(Func), "", &RI);
+}
+
+// visitUnwindInst - We want to destroy the setjmp map upon exit from the
+// function.
+void LowerSetJmp::visitUnwindInst(UnwindInst &UI) {
+ Function* Func = UI.getParent()->getParent();
+ new CallInst(DestroySJMap, GetSetJmpMap(Func), "", &UI);
+}
+
+ModulePass *llvm::createLowerSetJmpPass() {
+ return new LowerSetJmp();
+}
+
diff --git a/lib/Transforms/IPO/Makefile b/lib/Transforms/IPO/Makefile
new file mode 100644
index 0000000..22a76d3
--- /dev/null
+++ b/lib/Transforms/IPO/Makefile
@@ -0,0 +1,15 @@
+##===- lib/Transforms/IPO/Makefile -------------------------*- Makefile -*-===##
+#
+# 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.
+#
+##===----------------------------------------------------------------------===##
+
+LEVEL = ../../..
+LIBRARYNAME = LLVMipo
+BUILD_ARCHIVE = 1
+
+include $(LEVEL)/Makefile.common
+
diff --git a/lib/Transforms/IPO/PruneEH.cpp b/lib/Transforms/IPO/PruneEH.cpp
new file mode 100644
index 0000000..a783272
--- /dev/null
+++ b/lib/Transforms/IPO/PruneEH.cpp
@@ -0,0 +1,233 @@
+//===- PruneEH.cpp - Pass which deletes unused exception handlers ---------===//
+//
+// 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 implements a simple interprocedural pass which walks the
+// call-graph, turning invoke instructions into calls, iff the callee cannot
+// throw an exception. It implements this as a bottom-up traversal of the
+// call-graph.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "prune-eh"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/CallGraphSCCPass.h"
+#include "llvm/Constants.h"
+#include "llvm/Function.h"
+#include "llvm/Intrinsics.h"
+#include "llvm/Instructions.h"
+#include "llvm/Analysis/CallGraph.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/CFG.h"
+#include "llvm/Support/Compiler.h"
+#include <set>
+#include <algorithm>
+using namespace llvm;
+
+STATISTIC(NumRemoved, "Number of invokes removed");
+STATISTIC(NumUnreach, "Number of noreturn calls optimized");
+
+namespace {
+ struct VISIBILITY_HIDDEN PruneEH : public CallGraphSCCPass {
+ static char ID; // Pass identification, replacement for typeid
+ PruneEH() : CallGraphSCCPass((intptr_t)&ID) {}
+
+ /// DoesNotUnwind - This set contains all of the functions which we have
+ /// determined cannot unwind.
+ std::set<CallGraphNode*> DoesNotUnwind;
+
+ /// DoesNotReturn - This set contains all of the functions which we have
+ /// determined cannot return normally (but might unwind).
+ std::set<CallGraphNode*> DoesNotReturn;
+
+ // runOnSCC - Analyze the SCC, performing the transformation if possible.
+ bool runOnSCC(const std::vector<CallGraphNode *> &SCC);
+
+ bool SimplifyFunction(Function *F);
+ void DeleteBasicBlock(BasicBlock *BB);
+ };
+
+ char PruneEH::ID = 0;
+ RegisterPass<PruneEH> X("prune-eh", "Remove unused exception handling info");
+}
+
+Pass *llvm::createPruneEHPass() { return new PruneEH(); }
+
+
+bool PruneEH::runOnSCC(const std::vector<CallGraphNode *> &SCC) {
+ CallGraph &CG = getAnalysis<CallGraph>();
+ bool MadeChange = false;
+
+ // First pass, scan all of the functions in the SCC, simplifying them
+ // according to what we know.
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i)
+ if (Function *F = SCC[i]->getFunction())
+ MadeChange |= SimplifyFunction(F);
+
+ // Next, check to see if any callees might throw or if there are any external
+ // functions in this SCC: if so, we cannot prune any functions in this SCC.
+ // If this SCC includes the unwind instruction, we KNOW it throws, so
+ // obviously the SCC might throw.
+ //
+ bool SCCMightUnwind = false, SCCMightReturn = false;
+ for (unsigned i = 0, e = SCC.size();
+ (!SCCMightUnwind || !SCCMightReturn) && i != e; ++i) {
+ Function *F = SCC[i]->getFunction();
+ if (F == 0 || (F->isDeclaration() && !F->getIntrinsicID())) {
+ SCCMightUnwind = true;
+ SCCMightReturn = true;
+ } else {
+ if (F->isDeclaration())
+ SCCMightReturn = true;
+
+ // Check to see if this function performs an unwind or calls an
+ // unwinding function.
+ for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
+ if (isa<UnwindInst>(BB->getTerminator())) { // Uses unwind!
+ SCCMightUnwind = true;
+ } else if (isa<ReturnInst>(BB->getTerminator())) {
+ SCCMightReturn = true;
+ }
+
+ // Invoke instructions don't allow unwinding to continue, so we are
+ // only interested in call instructions.
+ if (!SCCMightUnwind)
+ for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; ++I)
+ if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ if (Function *Callee = CI->getCalledFunction()) {
+ CallGraphNode *CalleeNode = CG[Callee];
+ // If the callee is outside our current SCC, or if it is not
+ // known to throw, then we might throw also.
+ if (std::find(SCC.begin(), SCC.end(), CalleeNode) == SCC.end()&&
+ !DoesNotUnwind.count(CalleeNode)) {
+ SCCMightUnwind = true;
+ break;
+ }
+ } else {
+ // Indirect call, it might throw.
+ SCCMightUnwind = true;
+ break;
+ }
+ }
+ if (SCCMightUnwind && SCCMightReturn) break;
+ }
+ }
+ }
+
+ // If the SCC doesn't unwind or doesn't throw, note this fact.
+ if (!SCCMightUnwind)
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i)
+ DoesNotUnwind.insert(SCC[i]);
+ if (!SCCMightReturn)
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i)
+ DoesNotReturn.insert(SCC[i]);
+
+ for (unsigned i = 0, e = SCC.size(); i != e; ++i) {
+ // Convert any invoke instructions to non-throwing functions in this node
+ // into call instructions with a branch. This makes the exception blocks
+ // dead.
+ if (Function *F = SCC[i]->getFunction())
+ MadeChange |= SimplifyFunction(F);
+ }
+
+ return MadeChange;
+}
+
+
+// SimplifyFunction - Given information about callees, simplify the specified
+// function if we have invokes to non-unwinding functions or code after calls to
+// no-return functions.
+bool PruneEH::SimplifyFunction(Function *F) {
+ CallGraph &CG = getAnalysis<CallGraph>();
+ bool MadeChange = false;
+ for (Function::iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
+ if (InvokeInst *II = dyn_cast<InvokeInst>(BB->getTerminator()))
+ if (Function *F = II->getCalledFunction())
+ if (DoesNotUnwind.count(CG[F])) {
+ SmallVector<Value*, 8> Args(II->op_begin()+3, II->op_end());
+ // Insert a call instruction before the invoke.
+ CallInst *Call = new CallInst(II->getCalledValue(),
+ &Args[0], Args.size(), "", II);
+ Call->takeName(II);
+ Call->setCallingConv(II->getCallingConv());
+
+ // Anything that used the value produced by the invoke instruction
+ // now uses the value produced by the call instruction.
+ II->replaceAllUsesWith(Call);
+ BasicBlock *UnwindBlock = II->getUnwindDest();
+ UnwindBlock->removePredecessor(II->getParent());
+
+ // Insert a branch to the normal destination right before the
+ // invoke.
+ new BranchInst(II->getNormalDest(), II);
+
+ // Finally, delete the invoke instruction!
+ BB->getInstList().pop_back();
+
+ // If the unwind block is now dead, nuke it.
+ if (pred_begin(UnwindBlock) == pred_end(UnwindBlock))
+ DeleteBasicBlock(UnwindBlock); // Delete the new BB.
+
+ ++NumRemoved;
+ MadeChange = true;
+ }
+
+ for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
+ if (CallInst *CI = dyn_cast<CallInst>(I++))
+ if (Function *Callee = CI->getCalledFunction())
+ if (DoesNotReturn.count(CG[Callee]) && !isa<UnreachableInst>(I)) {
+ // This call calls a function that cannot return. Insert an
+ // unreachable instruction after it and simplify the code. Do this
+ // by splitting the BB, adding the unreachable, then deleting the
+ // new BB.
+ BasicBlock *New = BB->splitBasicBlock(I);
+
+ // Remove the uncond branch and add an unreachable.
+ BB->getInstList().pop_back();
+ new UnreachableInst(BB);
+
+ DeleteBasicBlock(New); // Delete the new BB.
+ MadeChange = true;
+ ++NumUnreach;
+ break;
+ }
+
+ }
+ return MadeChange;
+}
+
+/// DeleteBasicBlock - remove the specified basic block from the program,
+/// updating the callgraph to reflect any now-obsolete edges due to calls that
+/// exist in the BB.
+void PruneEH::DeleteBasicBlock(BasicBlock *BB) {
+ assert(pred_begin(BB) == pred_end(BB) && "BB is not dead!");
+ CallGraph &CG = getAnalysis<CallGraph>();
+
+ CallGraphNode *CGN = CG[BB->getParent()];
+ for (BasicBlock::iterator I = BB->end(), E = BB->begin(); I != E; ) {
+ --I;
+ if (CallInst *CI = dyn_cast<CallInst>(I)) {
+ if (Function *Callee = CI->getCalledFunction())
+ CGN->removeCallEdgeTo(CG[Callee]);
+ } else if (InvokeInst *II = dyn_cast<InvokeInst>(I)) {
+ if (Function *Callee = II->getCalledFunction())
+ CGN->removeCallEdgeTo(CG[Callee]);
+ }
+ if (!I->use_empty())
+ I->replaceAllUsesWith(UndefValue::get(I->getType()));
+ }
+
+ // Get the list of successors of this block.
+ std::vector<BasicBlock*> Succs(succ_begin(BB), succ_end(BB));
+
+ for (unsigned i = 0, e = Succs.size(); i != e; ++i)
+ Succs[i]->removePredecessor(BB);
+
+ BB->eraseFromParent();
+}
diff --git a/lib/Transforms/IPO/RaiseAllocations.cpp b/lib/Transforms/IPO/RaiseAllocations.cpp
new file mode 100644
index 0000000..5d2d9dd
--- /dev/null
+++ b/lib/Transforms/IPO/RaiseAllocations.cpp
@@ -0,0 +1,249 @@
+//===- RaiseAllocations.cpp - Convert %malloc & %free calls to insts ------===//
+//
+// 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 defines the RaiseAllocations pass which convert malloc and free
+// calls to malloc and free instructions.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "raiseallocs"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Module.h"
+#include "llvm/Instructions.h"
+#include "llvm/Pass.h"
+#include "llvm/Support/CallSite.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/ADT/Statistic.h"
+#include <algorithm>
+using namespace llvm;
+
+STATISTIC(NumRaised, "Number of allocations raised");
+
+namespace {
+ // RaiseAllocations - Turn %malloc and %free calls into the appropriate
+ // instruction.
+ //
+ class VISIBILITY_HIDDEN RaiseAllocations : public ModulePass {
+ Function *MallocFunc; // Functions in the module we are processing
+ Function *FreeFunc; // Initialized by doPassInitializationVirt
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ RaiseAllocations()
+ : ModulePass((intptr_t)&ID), MallocFunc(0), FreeFunc(0) {}
+
+ // doPassInitialization - For the raise allocations pass, this finds a
+ // declaration for malloc and free if they exist.
+ //
+ void doInitialization(Module &M);
+
+ // run - This method does the actual work of converting instructions over.
+ //
+ bool runOnModule(Module &M);
+ };
+
+ char RaiseAllocations::ID = 0;
+ RegisterPass<RaiseAllocations>
+ X("raiseallocs", "Raise allocations from calls to instructions");
+} // end anonymous namespace
+
+
+// createRaiseAllocationsPass - The interface to this file...
+ModulePass *llvm::createRaiseAllocationsPass() {
+ return new RaiseAllocations();
+}
+
+
+// If the module has a symbol table, they might be referring to the malloc and
+// free functions. If this is the case, grab the method pointers that the
+// module is using.
+//
+// Lookup %malloc and %free in the symbol table, for later use. If they don't
+// exist, or are not external, we do not worry about converting calls to that
+// function into the appropriate instruction.
+//
+void RaiseAllocations::doInitialization(Module &M) {
+
+ // Get Malloc and free prototypes if they exist!
+ MallocFunc = M.getFunction("malloc");
+ if (MallocFunc) {
+ const FunctionType* TyWeHave = MallocFunc->getFunctionType();
+
+ // Get the expected prototype for malloc
+ const FunctionType *Malloc1Type =
+ FunctionType::get(PointerType::get(Type::Int8Ty),
+ std::vector<const Type*>(1, Type::Int64Ty), false);
+
+ // Chck to see if we got the expected malloc
+ if (TyWeHave != Malloc1Type) {
+ // Check to see if the prototype is wrong, giving us sbyte*(uint) * malloc
+ // This handles the common declaration of: 'void *malloc(unsigned);'
+ const FunctionType *Malloc2Type =
+ FunctionType::get(PointerType::get(Type::Int8Ty),
+ std::vector<const Type*>(1, Type::Int32Ty), false);
+ if (TyWeHave != Malloc2Type) {
+ // Check to see if the prototype is missing, giving us
+ // sbyte*(...) * malloc
+ // This handles the common declaration of: 'void *malloc();'
+ const FunctionType *Malloc3Type =
+ FunctionType::get(PointerType::get(Type::Int8Ty),
+ std::vector<const Type*>(), true);
+ if (TyWeHave != Malloc3Type)
+ // Give up
+ MallocFunc = 0;
+ }
+ }
+ }
+
+ FreeFunc = M.getFunction("free");
+ if (FreeFunc) {
+ const FunctionType* TyWeHave = FreeFunc->getFunctionType();
+
+ // Get the expected prototype for void free(i8*)
+ const FunctionType *Free1Type = FunctionType::get(Type::VoidTy,
+ std::vector<const Type*>(1, PointerType::get(Type::Int8Ty)), false);
+
+ if (TyWeHave != Free1Type) {
+ // Check to see if the prototype was forgotten, giving us
+ // void (...) * free
+ // This handles the common forward declaration of: 'void free();'
+ const FunctionType* Free2Type = FunctionType::get(Type::VoidTy,
+ std::vector<const Type*>(),true);
+
+ if (TyWeHave != Free2Type) {
+ // One last try, check to see if we can find free as
+ // int (...)* free. This handles the case where NOTHING was declared.
+ const FunctionType* Free3Type = FunctionType::get(Type::Int32Ty,
+ std::vector<const Type*>(),true);
+
+ if (TyWeHave != Free3Type) {
+ // Give up.
+ FreeFunc = 0;
+ }
+ }
+ }
+ }
+
+ // Don't mess with locally defined versions of these functions...
+ if (MallocFunc && !MallocFunc->isDeclaration()) MallocFunc = 0;
+ if (FreeFunc && !FreeFunc->isDeclaration()) FreeFunc = 0;
+}
+
+// run - Transform calls into instructions...
+//
+bool RaiseAllocations::runOnModule(Module &M) {
+ // Find the malloc/free prototypes...
+ doInitialization(M);
+
+ bool Changed = false;
+
+ // First, process all of the malloc calls...
+ if (MallocFunc) {
+ std::vector<User*> Users(MallocFunc->use_begin(), MallocFunc->use_end());
+ std::vector<Value*> EqPointers; // Values equal to MallocFunc
+ while (!Users.empty()) {
+ User *U = Users.back();
+ Users.pop_back();
+
+ if (Instruction *I = dyn_cast<Instruction>(U)) {
+ CallSite CS = CallSite::get(I);
+ if (CS.getInstruction() && CS.arg_begin() != CS.arg_end() &&
+ (CS.getCalledFunction() == MallocFunc ||
+ std::find(EqPointers.begin(), EqPointers.end(),
+ CS.getCalledValue()) != EqPointers.end())) {
+
+ Value *Source = *CS.arg_begin();
+
+ // If no prototype was provided for malloc, we may need to cast the
+ // source size.
+ if (Source->getType() != Type::Int32Ty)
+ Source =
+ CastInst::createIntegerCast(Source, Type::Int32Ty, false/*ZExt*/,
+ "MallocAmtCast", I);
+
+ MallocInst *MI = new MallocInst(Type::Int8Ty, Source, "", I);
+ MI->takeName(I);
+ I->replaceAllUsesWith(MI);
+
+ // If the old instruction was an invoke, add an unconditional branch
+ // before the invoke, which will become the new terminator.
+ if (InvokeInst *II = dyn_cast<InvokeInst>(I))
+ new BranchInst(II->getNormalDest(), I);
+
+ // Delete the old call site
+ MI->getParent()->getInstList().erase(I);
+ Changed = true;
+ ++NumRaised;
+ }
+ } else if (GlobalValue *GV = dyn_cast<GlobalValue>(U)) {
+ Users.insert(Users.end(), GV->use_begin(), GV->use_end());
+ EqPointers.push_back(GV);
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
+ if (CE->isCast()) {
+ Users.insert(Users.end(), CE->use_begin(), CE->use_end());
+ EqPointers.push_back(CE);
+ }
+ }
+ }
+ }
+
+ // Next, process all free calls...
+ if (FreeFunc) {
+ std::vector<User*> Users(FreeFunc->use_begin(), FreeFunc->use_end());
+ std::vector<Value*> EqPointers; // Values equal to FreeFunc
+
+ while (!Users.empty()) {
+ User *U = Users.back();
+ Users.pop_back();
+
+ if (Instruction *I = dyn_cast<Instruction>(U)) {
+ CallSite CS = CallSite::get(I);
+ if (CS.getInstruction() && CS.arg_begin() != CS.arg_end() &&
+ (CS.getCalledFunction() == FreeFunc ||
+ std::find(EqPointers.begin(), EqPointers.end(),
+ CS.getCalledValue()) != EqPointers.end())) {
+
+ // If no prototype was provided for free, we may need to cast the
+ // source pointer. This should be really uncommon, but it's necessary
+ // just in case we are dealing with weird code like this:
+ // free((long)ptr);
+ //
+ Value *Source = *CS.arg_begin();
+ if (!isa<PointerType>(Source->getType()))
+ Source = new IntToPtrInst(Source, PointerType::get(Type::Int8Ty),
+ "FreePtrCast", I);
+ new FreeInst(Source, I);
+
+ // If the old instruction was an invoke, add an unconditional branch
+ // before the invoke, which will become the new terminator.
+ if (InvokeInst *II = dyn_cast<InvokeInst>(I))
+ new BranchInst(II->getNormalDest(), I);
+
+ // Delete the old call site
+ if (I->getType() != Type::VoidTy)
+ I->replaceAllUsesWith(UndefValue::get(I->getType()));
+ I->eraseFromParent();
+ Changed = true;
+ ++NumRaised;
+ }
+ } else if (GlobalValue *GV = dyn_cast<GlobalValue>(U)) {
+ Users.insert(Users.end(), GV->use_begin(), GV->use_end());
+ EqPointers.push_back(GV);
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U)) {
+ if (CE->isCast()) {
+ Users.insert(Users.end(), CE->use_begin(), CE->use_end());
+ EqPointers.push_back(CE);
+ }
+ }
+ }
+ }
+
+ return Changed;
+}
diff --git a/lib/Transforms/IPO/SimplifyLibCalls.cpp b/lib/Transforms/IPO/SimplifyLibCalls.cpp
new file mode 100644
index 0000000..b0f9128
--- /dev/null
+++ b/lib/Transforms/IPO/SimplifyLibCalls.cpp
@@ -0,0 +1,2021 @@
+//===- SimplifyLibCalls.cpp - Optimize specific well-known library calls --===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file implements a module pass that applies a variety of small
+// optimizations for calls to specific well-known function calls (e.g. runtime
+// library functions). For example, a call to the function "exit(3)" that
+// occurs within the main() function can be transformed into a simple "return 3"
+// instruction. Any optimization that takes this form (replace call to library
+// function with simpler code that provides the same result) belongs in this
+// file.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "simplify-libcalls"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/ADT/hash_map"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Config/config.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/Debug.h"
+#include "llvm/Target/TargetData.h"
+#include "llvm/Transforms/IPO.h"
+using namespace llvm;
+
+/// This statistic keeps track of the total number of library calls that have
+/// been simplified regardless of which call it is.
+STATISTIC(SimplifiedLibCalls, "Number of library calls simplified");
+
+namespace {
+ // Forward declarations
+ class LibCallOptimization;
+ class SimplifyLibCalls;
+
+/// This list is populated by the constructor for LibCallOptimization class.
+/// Therefore all subclasses are registered here at static initialization time
+/// and this list is what the SimplifyLibCalls pass uses to apply the individual
+/// optimizations to the call sites.
+/// @brief The list of optimizations deriving from LibCallOptimization
+static LibCallOptimization *OptList = 0;
+
+/// This class is the abstract base class for the set of optimizations that
+/// corresponds to one library call. The SimplifyLibCalls pass will call the
+/// ValidateCalledFunction method to ask the optimization if a given Function
+/// is the kind that the optimization can handle. If the subclass returns true,
+/// then SImplifyLibCalls will also call the OptimizeCall method to perform,
+/// or attempt to perform, the optimization(s) for the library call. Otherwise,
+/// OptimizeCall won't be called. Subclasses are responsible for providing the
+/// name of the library call (strlen, strcpy, etc.) to the LibCallOptimization
+/// constructor. This is used to efficiently select which call instructions to
+/// optimize. The criteria for a "lib call" is "anything with well known
+/// semantics", typically a library function that is defined by an international
+/// standard. Because the semantics are well known, the optimizations can
+/// generally short-circuit actually calling the function if there's a simpler
+/// way (e.g. strlen(X) can be reduced to a constant if X is a constant global).
+/// @brief Base class for library call optimizations
+class VISIBILITY_HIDDEN LibCallOptimization {
+ LibCallOptimization **Prev, *Next;
+ const char *FunctionName; ///< Name of the library call we optimize
+#ifndef NDEBUG
+ Statistic occurrences; ///< debug statistic (-debug-only=simplify-libcalls)
+#endif
+public:
+ /// The \p fname argument must be the name of the library function being
+ /// optimized by the subclass.
+ /// @brief Constructor that registers the optimization.
+ LibCallOptimization(const char *FName, const char *Description)
+ : FunctionName(FName) {
+
+#ifndef NDEBUG
+ occurrences.construct("simplify-libcalls", Description);
+#endif
+ // Register this optimizer in the list of optimizations.
+ Next = OptList;
+ OptList = this;
+ Prev = &OptList;
+ if (Next) Next->Prev = &Next;
+ }
+
+ /// getNext - All libcall optimizations are chained together into a list,
+ /// return the next one in the list.
+ LibCallOptimization *getNext() { return Next; }
+
+ /// @brief Deregister from the optlist
+ virtual ~LibCallOptimization() {
+ *Prev = Next;
+ if (Next) Next->Prev = Prev;
+ }
+
+ /// The implementation of this function in subclasses should determine if
+ /// \p F is suitable for the optimization. This method is called by
+ /// SimplifyLibCalls::runOnModule to short circuit visiting all the call
+ /// sites of such a function if that function is not suitable in the first
+ /// place. If the called function is suitabe, this method should return true;
+ /// false, otherwise. This function should also perform any lazy
+ /// initialization that the LibCallOptimization needs to do, if its to return
+ /// true. This avoids doing initialization until the optimizer is actually
+ /// going to be called upon to do some optimization.
+ /// @brief Determine if the function is suitable for optimization
+ virtual bool ValidateCalledFunction(
+ const Function* F, ///< The function that is the target of call sites
+ SimplifyLibCalls& SLC ///< The pass object invoking us
+ ) = 0;
+
+ /// The implementations of this function in subclasses is the heart of the
+ /// SimplifyLibCalls algorithm. Sublcasses of this class implement
+ /// OptimizeCall to determine if (a) the conditions are right for optimizing
+ /// the call and (b) to perform the optimization. If an action is taken
+ /// against ci, the subclass is responsible for returning true and ensuring
+ /// that ci is erased from its parent.
+ /// @brief Optimize a call, if possible.
+ virtual bool OptimizeCall(
+ CallInst* ci, ///< The call instruction that should be optimized.
+ SimplifyLibCalls& SLC ///< The pass object invoking us
+ ) = 0;
+
+ /// @brief Get the name of the library call being optimized
+ const char *getFunctionName() const { return FunctionName; }
+
+ bool ReplaceCallWith(CallInst *CI, Value *V) {
+ if (!CI->use_empty())
+ CI->replaceAllUsesWith(V);
+ CI->eraseFromParent();
+ return true;
+ }
+
+ /// @brief Called by SimplifyLibCalls to update the occurrences statistic.
+ void succeeded() {
+#ifndef NDEBUG
+ DEBUG(++occurrences);
+#endif
+ }
+};
+
+/// This class is an LLVM Pass that applies each of the LibCallOptimization
+/// instances to all the call sites in a module, relatively efficiently. The
+/// purpose of this pass is to provide optimizations for calls to well-known
+/// functions with well-known semantics, such as those in the c library. The
+/// class provides the basic infrastructure for handling runOnModule. Whenever
+/// this pass finds a function call, it asks the appropriate optimizer to
+/// validate the call (ValidateLibraryCall). If it is validated, then
+/// the OptimizeCall method is also called.
+/// @brief A ModulePass for optimizing well-known function calls.
+class VISIBILITY_HIDDEN SimplifyLibCalls : public ModulePass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ SimplifyLibCalls() : ModulePass((intptr_t)&ID) {}
+
+ /// We need some target data for accurate signature details that are
+ /// target dependent. So we require target data in our AnalysisUsage.
+ /// @brief Require TargetData from AnalysisUsage.
+ virtual void getAnalysisUsage(AnalysisUsage& Info) const {
+ // Ask that the TargetData analysis be performed before us so we can use
+ // the target data.
+ Info.addRequired<TargetData>();
+ }
+
+ /// For this pass, process all of the function calls in the module, calling
+ /// ValidateLibraryCall and OptimizeCall as appropriate.
+ /// @brief Run all the lib call optimizations on a Module.
+ virtual bool runOnModule(Module &M) {
+ reset(M);
+
+ bool result = false;
+ hash_map<std::string, LibCallOptimization*> OptznMap;
+ for (LibCallOptimization *Optzn = OptList; Optzn; Optzn = Optzn->getNext())
+ OptznMap[Optzn->getFunctionName()] = Optzn;
+
+ // The call optimizations can be recursive. That is, the optimization might
+ // generate a call to another function which can also be optimized. This way
+ // we make the LibCallOptimization instances very specific to the case they
+ // handle. It also means we need to keep running over the function calls in
+ // the module until we don't get any more optimizations possible.
+ bool found_optimization = false;
+ do {
+ found_optimization = false;
+ for (Module::iterator FI = M.begin(), FE = M.end(); FI != FE; ++FI) {
+ // All the "well-known" functions are external and have external linkage
+ // because they live in a runtime library somewhere and were (probably)
+ // not compiled by LLVM. So, we only act on external functions that
+ // have external or dllimport linkage and non-empty uses.
+ if (!FI->isDeclaration() ||
+ !(FI->hasExternalLinkage() || FI->hasDLLImportLinkage()) ||
+ FI->use_empty())
+ continue;
+
+ // Get the optimization class that pertains to this function
+ hash_map<std::string, LibCallOptimization*>::iterator OMI =
+ OptznMap.find(FI->getName());
+ if (OMI == OptznMap.end()) continue;
+
+ LibCallOptimization *CO = OMI->second;
+
+ // Make sure the called function is suitable for the optimization
+ if (!CO->ValidateCalledFunction(FI, *this))
+ continue;
+
+ // Loop over each of the uses of the function
+ for (Value::use_iterator UI = FI->use_begin(), UE = FI->use_end();
+ UI != UE ; ) {
+ // If the use of the function is a call instruction
+ if (CallInst* CI = dyn_cast<CallInst>(*UI++)) {
+ // Do the optimization on the LibCallOptimization.
+ if (CO->OptimizeCall(CI, *this)) {
+ ++SimplifiedLibCalls;
+ found_optimization = result = true;
+ CO->succeeded();
+ }
+ }
+ }
+ }
+ } while (found_optimization);
+
+ return result;
+ }
+
+ /// @brief Return the *current* module we're working on.
+ Module* getModule() const { return M; }
+
+ /// @brief Return the *current* target data for the module we're working on.
+ TargetData* getTargetData() const { return TD; }
+
+ /// @brief Return the size_t type -- syntactic shortcut
+ const Type* getIntPtrType() const { return TD->getIntPtrType(); }
+
+ /// @brief Return a Function* for the putchar libcall
+ Constant *get_putchar() {
+ if (!putchar_func)
+ putchar_func =
+ M->getOrInsertFunction("putchar", Type::Int32Ty, Type::Int32Ty, NULL);
+ return putchar_func;
+ }
+
+ /// @brief Return a Function* for the puts libcall
+ Constant *get_puts() {
+ if (!puts_func)
+ puts_func = M->getOrInsertFunction("puts", Type::Int32Ty,
+ PointerType::get(Type::Int8Ty),
+ NULL);
+ return puts_func;
+ }
+
+ /// @brief Return a Function* for the fputc libcall
+ Constant *get_fputc(const Type* FILEptr_type) {
+ if (!fputc_func)
+ fputc_func = M->getOrInsertFunction("fputc", Type::Int32Ty, Type::Int32Ty,
+ FILEptr_type, NULL);
+ return fputc_func;
+ }
+
+ /// @brief Return a Function* for the fputs libcall
+ Constant *get_fputs(const Type* FILEptr_type) {
+ if (!fputs_func)
+ fputs_func = M->getOrInsertFunction("fputs", Type::Int32Ty,
+ PointerType::get(Type::Int8Ty),
+ FILEptr_type, NULL);
+ return fputs_func;
+ }
+
+ /// @brief Return a Function* for the fwrite libcall
+ Constant *get_fwrite(const Type* FILEptr_type) {
+ if (!fwrite_func)
+ fwrite_func = M->getOrInsertFunction("fwrite", TD->getIntPtrType(),
+ PointerType::get(Type::Int8Ty),
+ TD->getIntPtrType(),
+ TD->getIntPtrType(),
+ FILEptr_type, NULL);
+ return fwrite_func;
+ }
+
+ /// @brief Return a Function* for the sqrt libcall
+ Constant *get_sqrt() {
+ if (!sqrt_func)
+ sqrt_func = M->getOrInsertFunction("sqrt", Type::DoubleTy,
+ Type::DoubleTy, NULL);
+ return sqrt_func;
+ }
+
+ /// @brief Return a Function* for the strcpy libcall
+ Constant *get_strcpy() {
+ if (!strcpy_func)
+ strcpy_func = M->getOrInsertFunction("strcpy",
+ PointerType::get(Type::Int8Ty),
+ PointerType::get(Type::Int8Ty),
+ PointerType::get(Type::Int8Ty),
+ NULL);
+ return strcpy_func;
+ }
+
+ /// @brief Return a Function* for the strlen libcall
+ Constant *get_strlen() {
+ if (!strlen_func)
+ strlen_func = M->getOrInsertFunction("strlen", TD->getIntPtrType(),
+ PointerType::get(Type::Int8Ty),
+ NULL);
+ return strlen_func;
+ }
+
+ /// @brief Return a Function* for the memchr libcall
+ Constant *get_memchr() {
+ if (!memchr_func)
+ memchr_func = M->getOrInsertFunction("memchr",
+ PointerType::get(Type::Int8Ty),
+ PointerType::get(Type::Int8Ty),
+ Type::Int32Ty, TD->getIntPtrType(),
+ NULL);
+ return memchr_func;
+ }
+
+ /// @brief Return a Function* for the memcpy libcall
+ Constant *get_memcpy() {
+ if (!memcpy_func) {
+ const Type *SBP = PointerType::get(Type::Int8Ty);
+ const char *N = TD->getIntPtrType() == Type::Int32Ty ?
+ "llvm.memcpy.i32" : "llvm.memcpy.i64";
+ memcpy_func = M->getOrInsertFunction(N, Type::VoidTy, SBP, SBP,
+ TD->getIntPtrType(), Type::Int32Ty,
+ NULL);
+ }
+ return memcpy_func;
+ }
+
+ Constant *getUnaryFloatFunction(const char *Name, Constant *&Cache) {
+ if (!Cache)
+ Cache = M->getOrInsertFunction(Name, Type::FloatTy, Type::FloatTy, NULL);
+ return Cache;
+ }
+
+ Constant *get_floorf() { return getUnaryFloatFunction("floorf", floorf_func);}
+ Constant *get_ceilf() { return getUnaryFloatFunction( "ceilf", ceilf_func);}
+ Constant *get_roundf() { return getUnaryFloatFunction("roundf", roundf_func);}
+ Constant *get_rintf() { return getUnaryFloatFunction( "rintf", rintf_func);}
+ Constant *get_nearbyintf() { return getUnaryFloatFunction("nearbyintf",
+ nearbyintf_func); }
+private:
+ /// @brief Reset our cached data for a new Module
+ void reset(Module& mod) {
+ M = &mod;
+ TD = &getAnalysis<TargetData>();
+ putchar_func = 0;
+ puts_func = 0;
+ fputc_func = 0;
+ fputs_func = 0;
+ fwrite_func = 0;
+ memcpy_func = 0;
+ memchr_func = 0;
+ sqrt_func = 0;
+ strcpy_func = 0;
+ strlen_func = 0;
+ floorf_func = 0;
+ ceilf_func = 0;
+ roundf_func = 0;
+ rintf_func = 0;
+ nearbyintf_func = 0;
+ }
+
+private:
+ /// Caches for function pointers.
+ Constant *putchar_func, *puts_func;
+ Constant *fputc_func, *fputs_func, *fwrite_func;
+ Constant *memcpy_func, *memchr_func;
+ Constant *sqrt_func;
+ Constant *strcpy_func, *strlen_func;
+ Constant *floorf_func, *ceilf_func, *roundf_func;
+ Constant *rintf_func, *nearbyintf_func;
+ Module *M; ///< Cached Module
+ TargetData *TD; ///< Cached TargetData
+};
+
+char SimplifyLibCalls::ID = 0;
+// Register the pass
+RegisterPass<SimplifyLibCalls>
+X("simplify-libcalls", "Simplify well-known library calls");
+
+} // anonymous namespace
+
+// The only public symbol in this file which just instantiates the pass object
+ModulePass *llvm::createSimplifyLibCallsPass() {
+ return new SimplifyLibCalls();
+}
+
+// Classes below here, in the anonymous namespace, are all subclasses of the
+// LibCallOptimization class, each implementing all optimizations possible for a
+// single well-known library call. Each has a static singleton instance that
+// auto registers it into the "optlist" global above.
+namespace {
+
+// Forward declare utility functions.
+static bool GetConstantStringInfo(Value *V, std::string &Str);
+static Value *CastToCStr(Value *V, Instruction *IP);
+
+/// This LibCallOptimization will find instances of a call to "exit" that occurs
+/// within the "main" function and change it to a simple "ret" instruction with
+/// the same value passed to the exit function. When this is done, it splits the
+/// basic block at the exit(3) call and deletes the call instruction.
+/// @brief Replace calls to exit in main with a simple return
+struct VISIBILITY_HIDDEN ExitInMainOptimization : public LibCallOptimization {
+ ExitInMainOptimization() : LibCallOptimization("exit",
+ "Number of 'exit' calls simplified") {}
+
+ // Make sure the called function looks like exit (int argument, int return
+ // type, external linkage, not varargs).
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ return F->arg_size() >= 1 && F->arg_begin()->getType()->isInteger();
+ }
+
+ virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& SLC) {
+ // To be careful, we check that the call to exit is coming from "main", that
+ // main has external linkage, and the return type of main and the argument
+ // to exit have the same type.
+ Function *from = ci->getParent()->getParent();
+ if (from->hasExternalLinkage())
+ if (from->getReturnType() == ci->getOperand(1)->getType())
+ if (from->getName() == "main") {
+ // Okay, time to actually do the optimization. First, get the basic
+ // block of the call instruction
+ BasicBlock* bb = ci->getParent();
+
+ // Create a return instruction that we'll replace the call with.
+ // Note that the argument of the return is the argument of the call
+ // instruction.
+ new ReturnInst(ci->getOperand(1), ci);
+
+ // Split the block at the call instruction which places it in a new
+ // basic block.
+ bb->splitBasicBlock(ci);
+
+ // The block split caused a branch instruction to be inserted into
+ // the end of the original block, right after the return instruction
+ // that we put there. That's not a valid block, so delete the branch
+ // instruction.
+ bb->getInstList().pop_back();
+
+ // Now we can finally get rid of the call instruction which now lives
+ // in the new basic block.
+ ci->eraseFromParent();
+
+ // Optimization succeeded, return true.
+ return true;
+ }
+ // We didn't pass the criteria for this optimization so return false
+ return false;
+ }
+} ExitInMainOptimizer;
+
+/// This LibCallOptimization will simplify a call to the strcat library
+/// function. The simplification is possible only if the string being
+/// concatenated is a constant array or a constant expression that results in
+/// a constant string. In this case we can replace it with strlen + llvm.memcpy
+/// of the constant string. Both of these calls are further reduced, if possible
+/// on subsequent passes.
+/// @brief Simplify the strcat library function.
+struct VISIBILITY_HIDDEN StrCatOptimization : public LibCallOptimization {
+public:
+ /// @brief Default constructor
+ StrCatOptimization() : LibCallOptimization("strcat",
+ "Number of 'strcat' calls simplified") {}
+
+public:
+
+ /// @brief Make sure that the "strcat" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getNumParams() == 2 &&
+ FT->getReturnType() == PointerType::get(Type::Int8Ty) &&
+ FT->getParamType(0) == FT->getReturnType() &&
+ FT->getParamType(1) == FT->getReturnType();
+ }
+
+ /// @brief Optimize the strcat library function
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // Extract some information from the instruction
+ Value *Dst = CI->getOperand(1);
+ Value *Src = CI->getOperand(2);
+
+ // Extract the initializer (while making numerous checks) from the
+ // source operand of the call to strcat.
+ std::string SrcStr;
+ if (!GetConstantStringInfo(Src, SrcStr))
+ return false;
+
+ // Handle the simple, do-nothing case
+ if (SrcStr.empty())
+ return ReplaceCallWith(CI, Dst);
+
+ // We need to find the end of the destination string. That's where the
+ // memory is to be moved to. We just generate a call to strlen.
+ CallInst *DstLen = new CallInst(SLC.get_strlen(), Dst,
+ Dst->getName()+".len", CI);
+
+ // Now that we have the destination's length, we must index into the
+ // destination's pointer to get the actual memcpy destination (end of
+ // the string .. we're concatenating).
+ Dst = new GetElementPtrInst(Dst, DstLen, Dst->getName()+".indexed", CI);
+
+ // We have enough information to now generate the memcpy call to
+ // do the concatenation for us.
+ Value *Vals[] = {
+ Dst, Src,
+ ConstantInt::get(SLC.getIntPtrType(), SrcStr.size()+1), // copy nul byte.
+ ConstantInt::get(Type::Int32Ty, 1) // alignment
+ };
+ new CallInst(SLC.get_memcpy(), Vals, 4, "", CI);
+
+ return ReplaceCallWith(CI, Dst);
+ }
+} StrCatOptimizer;
+
+/// This LibCallOptimization will simplify a call to the strchr library
+/// function. It optimizes out cases where the arguments are both constant
+/// and the result can be determined statically.
+/// @brief Simplify the strcmp library function.
+struct VISIBILITY_HIDDEN StrChrOptimization : public LibCallOptimization {
+public:
+ StrChrOptimization() : LibCallOptimization("strchr",
+ "Number of 'strchr' calls simplified") {}
+
+ /// @brief Make sure that the "strchr" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getNumParams() == 2 &&
+ FT->getReturnType() == PointerType::get(Type::Int8Ty) &&
+ FT->getParamType(0) == FT->getReturnType() &&
+ isa<IntegerType>(FT->getParamType(1));
+ }
+
+ /// @brief Perform the strchr optimizations
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // Check that the first argument to strchr is a constant array of sbyte.
+ std::string Str;
+ if (!GetConstantStringInfo(CI->getOperand(1), Str))
+ return false;
+
+ // If the second operand is not constant, just lower this to memchr since we
+ // know the length of the input string.
+ ConstantInt *CSI = dyn_cast<ConstantInt>(CI->getOperand(2));
+ if (!CSI) {
+ Value *Args[3] = {
+ CI->getOperand(1),
+ CI->getOperand(2),
+ ConstantInt::get(SLC.getIntPtrType(), Str.size()+1)
+ };
+ return ReplaceCallWith(CI, new CallInst(SLC.get_memchr(), Args, 3,
+ CI->getName(), CI));
+ }
+
+ // strchr can find the nul character.
+ Str += '\0';
+
+ // Get the character we're looking for
+ char CharValue = CSI->getSExtValue();
+
+ // Compute the offset
+ uint64_t i = 0;
+ while (1) {
+ if (i == Str.size()) // Didn't find the char. strchr returns null.
+ return ReplaceCallWith(CI, Constant::getNullValue(CI->getType()));
+ // Did we find our match?
+ if (Str[i] == CharValue)
+ break;
+ ++i;
+ }
+
+ // strchr(s+n,c) -> gep(s+n+i,c)
+ // (if c is a constant integer and s is a constant string)
+ Value *Idx = ConstantInt::get(Type::Int64Ty, i);
+ Value *GEP = new GetElementPtrInst(CI->getOperand(1), Idx,
+ CI->getOperand(1)->getName() +
+ ".strchr", CI);
+ return ReplaceCallWith(CI, GEP);
+ }
+} StrChrOptimizer;
+
+/// This LibCallOptimization will simplify a call to the strcmp library
+/// function. It optimizes out cases where one or both arguments are constant
+/// and the result can be determined statically.
+/// @brief Simplify the strcmp library function.
+struct VISIBILITY_HIDDEN StrCmpOptimization : public LibCallOptimization {
+public:
+ StrCmpOptimization() : LibCallOptimization("strcmp",
+ "Number of 'strcmp' calls simplified") {}
+
+ /// @brief Make sure that the "strcmp" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getReturnType() == Type::Int32Ty && FT->getNumParams() == 2 &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) == PointerType::get(Type::Int8Ty);
+ }
+
+ /// @brief Perform the strcmp optimization
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // First, check to see if src and destination are the same. If they are,
+ // then the optimization is to replace the CallInst with a constant 0
+ // because the call is a no-op.
+ Value *Str1P = CI->getOperand(1);
+ Value *Str2P = CI->getOperand(2);
+ if (Str1P == Str2P) // strcmp(x,x) -> 0
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));
+
+ std::string Str1;
+ if (!GetConstantStringInfo(Str1P, Str1))
+ return false;
+ if (Str1.empty()) {
+ // strcmp("", x) -> *x
+ Value *V = new LoadInst(Str2P, CI->getName()+".load", CI);
+ V = new ZExtInst(V, CI->getType(), CI->getName()+".int", CI);
+ return ReplaceCallWith(CI, V);
+ }
+
+ std::string Str2;
+ if (!GetConstantStringInfo(Str2P, Str2))
+ return false;
+ if (Str2.empty()) {
+ // strcmp(x,"") -> *x
+ Value *V = new LoadInst(Str1P, CI->getName()+".load", CI);
+ V = new ZExtInst(V, CI->getType(), CI->getName()+".int", CI);
+ return ReplaceCallWith(CI, V);
+ }
+
+ // strcmp(x, y) -> cnst (if both x and y are constant strings)
+ int R = strcmp(Str1.c_str(), Str2.c_str());
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), R));
+ }
+} StrCmpOptimizer;
+
+/// This LibCallOptimization will simplify a call to the strncmp library
+/// function. It optimizes out cases where one or both arguments are constant
+/// and the result can be determined statically.
+/// @brief Simplify the strncmp library function.
+struct VISIBILITY_HIDDEN StrNCmpOptimization : public LibCallOptimization {
+public:
+ StrNCmpOptimization() : LibCallOptimization("strncmp",
+ "Number of 'strncmp' calls simplified") {}
+
+ /// @brief Make sure that the "strncmp" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getReturnType() == Type::Int32Ty && FT->getNumParams() == 3 &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getParamType(0) == PointerType::get(Type::Int8Ty) &&
+ isa<IntegerType>(FT->getParamType(2));
+ return false;
+ }
+
+ /// @brief Perform the strncmp optimization
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // First, check to see if src and destination are the same. If they are,
+ // then the optimization is to replace the CallInst with a constant 0
+ // because the call is a no-op.
+ Value *Str1P = CI->getOperand(1);
+ Value *Str2P = CI->getOperand(2);
+ if (Str1P == Str2P) // strncmp(x,x, n) -> 0
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));
+
+ // Check the length argument, if it is Constant zero then the strings are
+ // considered equal.
+ uint64_t Length;
+ if (ConstantInt *LengthArg = dyn_cast<ConstantInt>(CI->getOperand(3)))
+ Length = LengthArg->getZExtValue();
+ else
+ return false;
+
+ if (Length == 0) // strncmp(x,y,0) -> 0
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));
+
+ std::string Str1;
+ if (!GetConstantStringInfo(Str1P, Str1))
+ return false;
+ if (Str1.empty()) {
+ // strncmp("", x, n) -> *x
+ Value *V = new LoadInst(Str2P, CI->getName()+".load", CI);
+ V = new ZExtInst(V, CI->getType(), CI->getName()+".int", CI);
+ return ReplaceCallWith(CI, V);
+ }
+
+ std::string Str2;
+ if (!GetConstantStringInfo(Str2P, Str2))
+ return false;
+ if (Str2.empty()) {
+ // strncmp(x, "", n) -> *x
+ Value *V = new LoadInst(Str1P, CI->getName()+".load", CI);
+ V = new ZExtInst(V, CI->getType(), CI->getName()+".int", CI);
+ return ReplaceCallWith(CI, V);
+ }
+
+ // strncmp(x, y, n) -> cnst (if both x and y are constant strings)
+ int R = strncmp(Str1.c_str(), Str2.c_str(), Length);
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), R));
+ }
+} StrNCmpOptimizer;
+
+/// This LibCallOptimization will simplify a call to the strcpy library
+/// function. Two optimizations are possible:
+/// (1) If src and dest are the same and not volatile, just return dest
+/// (2) If the src is a constant then we can convert to llvm.memmove
+/// @brief Simplify the strcpy library function.
+struct VISIBILITY_HIDDEN StrCpyOptimization : public LibCallOptimization {
+public:
+ StrCpyOptimization() : LibCallOptimization("strcpy",
+ "Number of 'strcpy' calls simplified") {}
+
+ /// @brief Make sure that the "strcpy" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getNumParams() == 2 &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ FT->getReturnType() == FT->getParamType(0) &&
+ FT->getParamType(0) == PointerType::get(Type::Int8Ty);
+ }
+
+ /// @brief Perform the strcpy optimization
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // First, check to see if src and destination are the same. If they are,
+ // then the optimization is to replace the CallInst with the destination
+ // because the call is a no-op. Note that this corresponds to the
+ // degenerate strcpy(X,X) case which should have "undefined" results
+ // according to the C specification. However, it occurs sometimes and
+ // we optimize it as a no-op.
+ Value *Dst = CI->getOperand(1);
+ Value *Src = CI->getOperand(2);
+ if (Dst == Src) {
+ // strcpy(x, x) -> x
+ return ReplaceCallWith(CI, Dst);
+ }
+
+ // Get the length of the constant string referenced by the Src operand.
+ std::string SrcStr;
+ if (!GetConstantStringInfo(Src, SrcStr))
+ return false;
+
+ // If the constant string's length is zero we can optimize this by just
+ // doing a store of 0 at the first byte of the destination
+ if (SrcStr.size() == 0) {
+ new StoreInst(ConstantInt::get(Type::Int8Ty, 0), Dst, CI);
+ return ReplaceCallWith(CI, Dst);
+ }
+
+ // We have enough information to now generate the memcpy call to
+ // do the concatenation for us.
+ Value *MemcpyOps[] = {
+ Dst, Src, // Pass length including nul byte.
+ ConstantInt::get(SLC.getIntPtrType(), SrcStr.size()+1),
+ ConstantInt::get(Type::Int32Ty, 1) // alignment
+ };
+ new CallInst(SLC.get_memcpy(), MemcpyOps, 4, "", CI);
+
+ return ReplaceCallWith(CI, Dst);
+ }
+} StrCpyOptimizer;
+
+/// This LibCallOptimization will simplify a call to the strlen library
+/// function by replacing it with a constant value if the string provided to
+/// it is a constant array.
+/// @brief Simplify the strlen library function.
+struct VISIBILITY_HIDDEN StrLenOptimization : public LibCallOptimization {
+ StrLenOptimization() : LibCallOptimization("strlen",
+ "Number of 'strlen' calls simplified") {}
+
+ /// @brief Make sure that the "strlen" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getNumParams() == 1 &&
+ FT->getParamType(0) == PointerType::get(Type::Int8Ty) &&
+ isa<IntegerType>(FT->getReturnType());
+ }
+
+ /// @brief Perform the strlen optimization
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // Make sure we're dealing with an sbyte* here.
+ Value *Src = CI->getOperand(1);
+
+ // Does the call to strlen have exactly one use?
+ if (CI->hasOneUse()) {
+ // Is that single use a icmp operator?
+ if (ICmpInst *Cmp = dyn_cast<ICmpInst>(CI->use_back()))
+ // Is it compared against a constant integer?
+ if (ConstantInt *Cst = dyn_cast<ConstantInt>(Cmp->getOperand(1))) {
+ // If its compared against length 0 with == or !=
+ if (Cst->getZExtValue() == 0 && Cmp->isEquality()) {
+ // strlen(x) != 0 -> *x != 0
+ // strlen(x) == 0 -> *x == 0
+ Value *V = new LoadInst(Src, Src->getName()+".first", CI);
+ V = new ICmpInst(Cmp->getPredicate(), V,
+ ConstantInt::get(Type::Int8Ty, 0),
+ Cmp->getName()+".strlen", CI);
+ Cmp->replaceAllUsesWith(V);
+ Cmp->eraseFromParent();
+ return ReplaceCallWith(CI, 0); // no uses.
+ }
+ }
+ }
+
+ // Get the length of the constant string operand
+ std::string Str;
+ if (!GetConstantStringInfo(Src, Str))
+ return false;
+
+ // strlen("xyz") -> 3 (for example)
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), Str.size()));
+ }
+} StrLenOptimizer;
+
+/// IsOnlyUsedInEqualsComparison - Return true if it only matters that the value
+/// is equal or not-equal to zero.
+static bool IsOnlyUsedInEqualsZeroComparison(Instruction *I) {
+ for (Value::use_iterator UI = I->use_begin(), E = I->use_end();
+ UI != E; ++UI) {
+ if (ICmpInst *IC = dyn_cast<ICmpInst>(*UI))
+ if (IC->isEquality())
+ if (Constant *C = dyn_cast<Constant>(IC->getOperand(1)))
+ if (C->isNullValue())
+ continue;
+ // Unknown instruction.
+ return false;
+ }
+ return true;
+}
+
+/// This memcmpOptimization will simplify a call to the memcmp library
+/// function.
+struct VISIBILITY_HIDDEN memcmpOptimization : public LibCallOptimization {
+ /// @brief Default Constructor
+ memcmpOptimization()
+ : LibCallOptimization("memcmp", "Number of 'memcmp' calls simplified") {}
+
+ /// @brief Make sure that the "memcmp" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &TD) {
+ Function::const_arg_iterator AI = F->arg_begin();
+ if (F->arg_size() != 3 || !isa<PointerType>(AI->getType())) return false;
+ if (!isa<PointerType>((++AI)->getType())) return false;
+ if (!(++AI)->getType()->isInteger()) return false;
+ if (!F->getReturnType()->isInteger()) return false;
+ return true;
+ }
+
+ /// Because of alignment and instruction information that we don't have, we
+ /// leave the bulk of this to the code generators.
+ ///
+ /// Note that we could do much more if we could force alignment on otherwise
+ /// small aligned allocas, or if we could indicate that loads have a small
+ /// alignment.
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &TD) {
+ Value *LHS = CI->getOperand(1), *RHS = CI->getOperand(2);
+
+ // If the two operands are the same, return zero.
+ if (LHS == RHS) {
+ // memcmp(s,s,x) -> 0
+ return ReplaceCallWith(CI, Constant::getNullValue(CI->getType()));
+ }
+
+ // Make sure we have a constant length.
+ ConstantInt *LenC = dyn_cast<ConstantInt>(CI->getOperand(3));
+ if (!LenC) return false;
+ uint64_t Len = LenC->getZExtValue();
+
+ // If the length is zero, this returns 0.
+ switch (Len) {
+ case 0:
+ // memcmp(s1,s2,0) -> 0
+ return ReplaceCallWith(CI, Constant::getNullValue(CI->getType()));
+ case 1: {
+ // memcmp(S1,S2,1) -> *(ubyte*)S1 - *(ubyte*)S2
+ const Type *UCharPtr = PointerType::get(Type::Int8Ty);
+ CastInst *Op1Cast = CastInst::create(
+ Instruction::BitCast, LHS, UCharPtr, LHS->getName(), CI);
+ CastInst *Op2Cast = CastInst::create(
+ Instruction::BitCast, RHS, UCharPtr, RHS->getName(), CI);
+ Value *S1V = new LoadInst(Op1Cast, LHS->getName()+".val", CI);
+ Value *S2V = new LoadInst(Op2Cast, RHS->getName()+".val", CI);
+ Value *RV = BinaryOperator::createSub(S1V, S2V, CI->getName()+".diff",CI);
+ if (RV->getType() != CI->getType())
+ RV = CastInst::createIntegerCast(RV, CI->getType(), false,
+ RV->getName(), CI);
+ return ReplaceCallWith(CI, RV);
+ }
+ case 2:
+ if (IsOnlyUsedInEqualsZeroComparison(CI)) {
+ // TODO: IF both are aligned, use a short load/compare.
+
+ // memcmp(S1,S2,2) -> S1[0]-S2[0] | S1[1]-S2[1] iff only ==/!= 0 matters
+ const Type *UCharPtr = PointerType::get(Type::Int8Ty);
+ CastInst *Op1Cast = CastInst::create(
+ Instruction::BitCast, LHS, UCharPtr, LHS->getName(), CI);
+ CastInst *Op2Cast = CastInst::create(
+ Instruction::BitCast, RHS, UCharPtr, RHS->getName(), CI);
+ Value *S1V1 = new LoadInst(Op1Cast, LHS->getName()+".val1", CI);
+ Value *S2V1 = new LoadInst(Op2Cast, RHS->getName()+".val1", CI);
+ Value *D1 = BinaryOperator::createSub(S1V1, S2V1,
+ CI->getName()+".d1", CI);
+ Constant *One = ConstantInt::get(Type::Int32Ty, 1);
+ Value *G1 = new GetElementPtrInst(Op1Cast, One, "next1v", CI);
+ Value *G2 = new GetElementPtrInst(Op2Cast, One, "next2v", CI);
+ Value *S1V2 = new LoadInst(G1, LHS->getName()+".val2", CI);
+ Value *S2V2 = new LoadInst(G2, RHS->getName()+".val2", CI);
+ Value *D2 = BinaryOperator::createSub(S1V2, S2V2,
+ CI->getName()+".d1", CI);
+ Value *Or = BinaryOperator::createOr(D1, D2, CI->getName()+".res", CI);
+ if (Or->getType() != CI->getType())
+ Or = CastInst::createIntegerCast(Or, CI->getType(), false /*ZExt*/,
+ Or->getName(), CI);
+ return ReplaceCallWith(CI, Or);
+ }
+ break;
+ default:
+ break;
+ }
+
+ return false;
+ }
+} memcmpOptimizer;
+
+
+/// This LibCallOptimization will simplify a call to the memcpy library
+/// function by expanding it out to a single store of size 0, 1, 2, 4, or 8
+/// bytes depending on the length of the string and the alignment. Additional
+/// optimizations are possible in code generation (sequence of immediate store)
+/// @brief Simplify the memcpy library function.
+struct VISIBILITY_HIDDEN LLVMMemCpyMoveOptzn : public LibCallOptimization {
+ LLVMMemCpyMoveOptzn(const char* fname, const char* desc)
+ : LibCallOptimization(fname, desc) {}
+
+ /// @brief Make sure that the "memcpy" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& TD) {
+ // Just make sure this has 4 arguments per LLVM spec.
+ return (f->arg_size() == 4);
+ }
+
+ /// Because of alignment and instruction information that we don't have, we
+ /// leave the bulk of this to the code generators. The optimization here just
+ /// deals with a few degenerate cases where the length of the string and the
+ /// alignment match the sizes of our intrinsic types so we can do a load and
+ /// store instead of the memcpy call.
+ /// @brief Perform the memcpy optimization.
+ virtual bool OptimizeCall(CallInst* ci, SimplifyLibCalls& TD) {
+ // Make sure we have constant int values to work with
+ ConstantInt* LEN = dyn_cast<ConstantInt>(ci->getOperand(3));
+ if (!LEN)
+ return false;
+ ConstantInt* ALIGN = dyn_cast<ConstantInt>(ci->getOperand(4));
+ if (!ALIGN)
+ return false;
+
+ // If the length is larger than the alignment, we can't optimize
+ uint64_t len = LEN->getZExtValue();
+ uint64_t alignment = ALIGN->getZExtValue();
+ if (alignment == 0)
+ alignment = 1; // Alignment 0 is identity for alignment 1
+ if (len > alignment)
+ return false;
+
+ // Get the type we will cast to, based on size of the string
+ Value* dest = ci->getOperand(1);
+ Value* src = ci->getOperand(2);
+ const Type* castType = 0;
+ switch (len) {
+ case 0:
+ // memcpy(d,s,0,a) -> d
+ return ReplaceCallWith(ci, 0);
+ case 1: castType = Type::Int8Ty; break;
+ case 2: castType = Type::Int16Ty; break;
+ case 4: castType = Type::Int32Ty; break;
+ case 8: castType = Type::Int64Ty; break;
+ default:
+ return false;
+ }
+
+ // Cast source and dest to the right sized primitive and then load/store
+ CastInst* SrcCast = CastInst::create(Instruction::BitCast,
+ src, PointerType::get(castType), src->getName()+".cast", ci);
+ CastInst* DestCast = CastInst::create(Instruction::BitCast,
+ dest, PointerType::get(castType),dest->getName()+".cast", ci);
+ LoadInst* LI = new LoadInst(SrcCast,SrcCast->getName()+".val",ci);
+ new StoreInst(LI, DestCast, ci);
+ return ReplaceCallWith(ci, 0);
+ }
+};
+
+/// This LibCallOptimization will simplify a call to the memcpy/memmove library
+/// functions.
+LLVMMemCpyMoveOptzn LLVMMemCpyOptimizer32("llvm.memcpy.i32",
+ "Number of 'llvm.memcpy' calls simplified");
+LLVMMemCpyMoveOptzn LLVMMemCpyOptimizer64("llvm.memcpy.i64",
+ "Number of 'llvm.memcpy' calls simplified");
+LLVMMemCpyMoveOptzn LLVMMemMoveOptimizer32("llvm.memmove.i32",
+ "Number of 'llvm.memmove' calls simplified");
+LLVMMemCpyMoveOptzn LLVMMemMoveOptimizer64("llvm.memmove.i64",
+ "Number of 'llvm.memmove' calls simplified");
+
+/// This LibCallOptimization will simplify a call to the memset library
+/// function by expanding it out to a single store of size 0, 1, 2, 4, or 8
+/// bytes depending on the length argument.
+struct VISIBILITY_HIDDEN LLVMMemSetOptimization : public LibCallOptimization {
+ /// @brief Default Constructor
+ LLVMMemSetOptimization(const char *Name) : LibCallOptimization(Name,
+ "Number of 'llvm.memset' calls simplified") {}
+
+ /// @brief Make sure that the "memset" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &TD) {
+ // Just make sure this has 3 arguments per LLVM spec.
+ return F->arg_size() == 4;
+ }
+
+ /// Because of alignment and instruction information that we don't have, we
+ /// leave the bulk of this to the code generators. The optimization here just
+ /// deals with a few degenerate cases where the length parameter is constant
+ /// and the alignment matches the sizes of our intrinsic types so we can do
+ /// store instead of the memcpy call. Other calls are transformed into the
+ /// llvm.memset intrinsic.
+ /// @brief Perform the memset optimization.
+ virtual bool OptimizeCall(CallInst *ci, SimplifyLibCalls &TD) {
+ // Make sure we have constant int values to work with
+ ConstantInt* LEN = dyn_cast<ConstantInt>(ci->getOperand(3));
+ if (!LEN)
+ return false;
+ ConstantInt* ALIGN = dyn_cast<ConstantInt>(ci->getOperand(4));
+ if (!ALIGN)
+ return false;
+
+ // Extract the length and alignment
+ uint64_t len = LEN->getZExtValue();
+ uint64_t alignment = ALIGN->getZExtValue();
+
+ // Alignment 0 is identity for alignment 1
+ if (alignment == 0)
+ alignment = 1;
+
+ // If the length is zero, this is a no-op
+ if (len == 0) {
+ // memset(d,c,0,a) -> noop
+ return ReplaceCallWith(ci, 0);
+ }
+
+ // If the length is larger than the alignment, we can't optimize
+ if (len > alignment)
+ return false;
+
+ // Make sure we have a constant ubyte to work with so we can extract
+ // the value to be filled.
+ ConstantInt* FILL = dyn_cast<ConstantInt>(ci->getOperand(2));
+ if (!FILL)
+ return false;
+ if (FILL->getType() != Type::Int8Ty)
+ return false;
+
+ // memset(s,c,n) -> store s, c (for n=1,2,4,8)
+
+ // Extract the fill character
+ uint64_t fill_char = FILL->getZExtValue();
+ uint64_t fill_value = fill_char;
+
+ // Get the type we will cast to, based on size of memory area to fill, and
+ // and the value we will store there.
+ Value* dest = ci->getOperand(1);
+ const Type* castType = 0;
+ switch (len) {
+ case 1:
+ castType = Type::Int8Ty;
+ break;
+ case 2:
+ castType = Type::Int16Ty;
+ fill_value |= fill_char << 8;
+ break;
+ case 4:
+ castType = Type::Int32Ty;
+ fill_value |= fill_char << 8 | fill_char << 16 | fill_char << 24;
+ break;
+ case 8:
+ castType = Type::Int64Ty;
+ fill_value |= fill_char << 8 | fill_char << 16 | fill_char << 24;
+ fill_value |= fill_char << 32 | fill_char << 40 | fill_char << 48;
+ fill_value |= fill_char << 56;
+ break;
+ default:
+ return false;
+ }
+
+ // Cast dest to the right sized primitive and then load/store
+ CastInst* DestCast = new BitCastInst(dest, PointerType::get(castType),
+ dest->getName()+".cast", ci);
+ new StoreInst(ConstantInt::get(castType,fill_value),DestCast, ci);
+ return ReplaceCallWith(ci, 0);
+ }
+};
+
+LLVMMemSetOptimization MemSet32Optimizer("llvm.memset.i32");
+LLVMMemSetOptimization MemSet64Optimizer("llvm.memset.i64");
+
+
+/// This LibCallOptimization will simplify calls to the "pow" library
+/// function. It looks for cases where the result of pow is well known and
+/// substitutes the appropriate value.
+/// @brief Simplify the pow library function.
+struct VISIBILITY_HIDDEN PowOptimization : public LibCallOptimization {
+public:
+ /// @brief Default Constructor
+ PowOptimization() : LibCallOptimization("pow",
+ "Number of 'pow' calls simplified") {}
+
+ /// @brief Make sure that the "pow" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC){
+ // Just make sure this has 2 arguments
+ return (f->arg_size() == 2);
+ }
+
+ /// @brief Perform the pow optimization.
+ virtual bool OptimizeCall(CallInst *ci, SimplifyLibCalls &SLC) {
+ const Type *Ty = cast<Function>(ci->getOperand(0))->getReturnType();
+ Value* base = ci->getOperand(1);
+ Value* expn = ci->getOperand(2);
+ if (ConstantFP *Op1 = dyn_cast<ConstantFP>(base)) {
+ double Op1V = Op1->getValue();
+ if (Op1V == 1.0) // pow(1.0,x) -> 1.0
+ return ReplaceCallWith(ci, ConstantFP::get(Ty, 1.0));
+ } else if (ConstantFP* Op2 = dyn_cast<ConstantFP>(expn)) {
+ double Op2V = Op2->getValue();
+ if (Op2V == 0.0) {
+ // pow(x,0.0) -> 1.0
+ return ReplaceCallWith(ci, ConstantFP::get(Ty,1.0));
+ } else if (Op2V == 0.5) {
+ // pow(x,0.5) -> sqrt(x)
+ CallInst* sqrt_inst = new CallInst(SLC.get_sqrt(), base,
+ ci->getName()+".pow",ci);
+ return ReplaceCallWith(ci, sqrt_inst);
+ } else if (Op2V == 1.0) {
+ // pow(x,1.0) -> x
+ return ReplaceCallWith(ci, base);
+ } else if (Op2V == -1.0) {
+ // pow(x,-1.0) -> 1.0/x
+ Value *div_inst =
+ BinaryOperator::createFDiv(ConstantFP::get(Ty, 1.0), base,
+ ci->getName()+".pow", ci);
+ return ReplaceCallWith(ci, div_inst);
+ }
+ }
+ return false; // opt failed
+ }
+} PowOptimizer;
+
+/// This LibCallOptimization will simplify calls to the "printf" library
+/// function. It looks for cases where the result of printf is not used and the
+/// operation can be reduced to something simpler.
+/// @brief Simplify the printf library function.
+struct VISIBILITY_HIDDEN PrintfOptimization : public LibCallOptimization {
+public:
+ /// @brief Default Constructor
+ PrintfOptimization() : LibCallOptimization("printf",
+ "Number of 'printf' calls simplified") {}
+
+ /// @brief Make sure that the "printf" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ // Just make sure this has at least 1 argument and returns an integer or
+ // void type.
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getNumParams() >= 1 &&
+ (isa<IntegerType>(FT->getReturnType()) ||
+ FT->getReturnType() == Type::VoidTy);
+ }
+
+ /// @brief Perform the printf optimization.
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // All the optimizations depend on the length of the first argument and the
+ // fact that it is a constant string array. Check that now
+ std::string FormatStr;
+ if (!GetConstantStringInfo(CI->getOperand(1), FormatStr))
+ return false;
+
+ // If this is a simple constant string with no format specifiers that ends
+ // with a \n, turn it into a puts call.
+ if (FormatStr.empty()) {
+ // Tolerate printf's declared void.
+ if (CI->use_empty()) return ReplaceCallWith(CI, 0);
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));
+ }
+
+ if (FormatStr.size() == 1) {
+ // Turn this into a putchar call, even if it is a %.
+ Value *V = ConstantInt::get(Type::Int32Ty, FormatStr[0]);
+ new CallInst(SLC.get_putchar(), V, "", CI);
+ if (CI->use_empty()) return ReplaceCallWith(CI, 0);
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 1));
+ }
+
+ // Check to see if the format str is something like "foo\n", in which case
+ // we convert it to a puts call. We don't allow it to contain any format
+ // characters.
+ if (FormatStr[FormatStr.size()-1] == '\n' &&
+ FormatStr.find('%') == std::string::npos) {
+ // Create a string literal with no \n on it. We expect the constant merge
+ // pass to be run after this pass, to merge duplicate strings.
+ FormatStr.erase(FormatStr.end()-1);
+ Constant *Init = ConstantArray::get(FormatStr, true);
+ Constant *GV = new GlobalVariable(Init->getType(), true,
+ GlobalVariable::InternalLinkage,
+ Init, "str",
+ CI->getParent()->getParent()->getParent());
+ // Cast GV to be a pointer to char.
+ GV = ConstantExpr::getBitCast(GV, PointerType::get(Type::Int8Ty));
+ new CallInst(SLC.get_puts(), GV, "", CI);
+
+ if (CI->use_empty()) return ReplaceCallWith(CI, 0);
+ return ReplaceCallWith(CI,
+ ConstantInt::get(CI->getType(), FormatStr.size()));
+ }
+
+
+ // Only support %c or "%s\n" for now.
+ if (FormatStr.size() < 2 || FormatStr[0] != '%')
+ return false;
+
+ // Get the second character and switch on its value
+ switch (FormatStr[1]) {
+ default: return false;
+ case 's':
+ if (FormatStr != "%s\n" || CI->getNumOperands() < 3 ||
+ // TODO: could insert strlen call to compute string length.
+ !CI->use_empty())
+ return false;
+
+ // printf("%s\n",str) -> puts(str)
+ new CallInst(SLC.get_puts(), CastToCStr(CI->getOperand(2), CI),
+ CI->getName(), CI);
+ return ReplaceCallWith(CI, 0);
+ case 'c': {
+ // printf("%c",c) -> putchar(c)
+ if (FormatStr.size() != 2 || CI->getNumOperands() < 3)
+ return false;
+
+ Value *V = CI->getOperand(2);
+ if (!isa<IntegerType>(V->getType()) ||
+ cast<IntegerType>(V->getType())->getBitWidth() > 32)
+ return false;
+
+ V = CastInst::createZExtOrBitCast(V, Type::Int32Ty, CI->getName()+".int",
+ CI);
+ new CallInst(SLC.get_putchar(), V, "", CI);
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 1));
+ }
+ }
+ }
+} PrintfOptimizer;
+
+/// This LibCallOptimization will simplify calls to the "fprintf" library
+/// function. It looks for cases where the result of fprintf is not used and the
+/// operation can be reduced to something simpler.
+/// @brief Simplify the fprintf library function.
+struct VISIBILITY_HIDDEN FPrintFOptimization : public LibCallOptimization {
+public:
+ /// @brief Default Constructor
+ FPrintFOptimization() : LibCallOptimization("fprintf",
+ "Number of 'fprintf' calls simplified") {}
+
+ /// @brief Make sure that the "fprintf" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getNumParams() == 2 && // two fixed arguments.
+ FT->getParamType(1) == PointerType::get(Type::Int8Ty) &&
+ isa<PointerType>(FT->getParamType(0)) &&
+ isa<IntegerType>(FT->getReturnType());
+ }
+
+ /// @brief Perform the fprintf optimization.
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // If the call has more than 3 operands, we can't optimize it
+ if (CI->getNumOperands() != 3 && CI->getNumOperands() != 4)
+ return false;
+
+ // All the optimizations depend on the format string.
+ std::string FormatStr;
+ if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
+ return false;
+
+ // If this is just a format string, turn it into fwrite.
+ if (CI->getNumOperands() == 3) {
+ for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
+ if (FormatStr[i] == '%')
+ return false; // we found a format specifier
+
+ // fprintf(file,fmt) -> fwrite(fmt,strlen(fmt),file)
+ const Type *FILEty = CI->getOperand(1)->getType();
+
+ Value *FWriteArgs[] = {
+ CI->getOperand(2),
+ ConstantInt::get(SLC.getIntPtrType(), FormatStr.size()),
+ ConstantInt::get(SLC.getIntPtrType(), 1),
+ CI->getOperand(1)
+ };
+ new CallInst(SLC.get_fwrite(FILEty), FWriteArgs, 4, CI->getName(), CI);
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(),
+ FormatStr.size()));
+ }
+
+ // The remaining optimizations require the format string to be length 2:
+ // "%s" or "%c".
+ if (FormatStr.size() != 2 || FormatStr[0] != '%')
+ return false;
+
+ // Get the second character and switch on its value
+ switch (FormatStr[1]) {
+ case 'c': {
+ // fprintf(file,"%c",c) -> fputc(c,file)
+ const Type *FILETy = CI->getOperand(1)->getType();
+ Value *C = CastInst::createZExtOrBitCast(CI->getOperand(3), Type::Int32Ty,
+ CI->getName()+".int", CI);
+ new CallInst(SLC.get_fputc(FILETy), C, CI->getOperand(1), "", CI);
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 1));
+ }
+ case 's': {
+ const Type *FILETy = CI->getOperand(1)->getType();
+
+ // If the result of the fprintf call is used, we can't do this.
+ // TODO: we should insert a strlen call.
+ if (!CI->use_empty())
+ return false;
+
+ // fprintf(file,"%s",str) -> fputs(str,file)
+ new CallInst(SLC.get_fputs(FILETy), CastToCStr(CI->getOperand(3), CI),
+ CI->getOperand(1), CI->getName(), CI);
+ return ReplaceCallWith(CI, 0);
+ }
+ default:
+ return false;
+ }
+ }
+} FPrintFOptimizer;
+
+/// This LibCallOptimization will simplify calls to the "sprintf" library
+/// function. It looks for cases where the result of sprintf is not used and the
+/// operation can be reduced to something simpler.
+/// @brief Simplify the sprintf library function.
+struct VISIBILITY_HIDDEN SPrintFOptimization : public LibCallOptimization {
+public:
+ /// @brief Default Constructor
+ SPrintFOptimization() : LibCallOptimization("sprintf",
+ "Number of 'sprintf' calls simplified") {}
+
+ /// @brief Make sure that the "sprintf" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getNumParams() == 2 && // two fixed arguments.
+ FT->getParamType(1) == PointerType::get(Type::Int8Ty) &&
+ FT->getParamType(0) == FT->getParamType(1) &&
+ isa<IntegerType>(FT->getReturnType());
+ }
+
+ /// @brief Perform the sprintf optimization.
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // If the call has more than 3 operands, we can't optimize it
+ if (CI->getNumOperands() != 3 && CI->getNumOperands() != 4)
+ return false;
+
+ std::string FormatStr;
+ if (!GetConstantStringInfo(CI->getOperand(2), FormatStr))
+ return false;
+
+ if (CI->getNumOperands() == 3) {
+ // Make sure there's no % in the constant array
+ for (unsigned i = 0, e = FormatStr.size(); i != e; ++i)
+ if (FormatStr[i] == '%')
+ return false; // we found a format specifier
+
+ // sprintf(str,fmt) -> llvm.memcpy(str,fmt,strlen(fmt),1)
+ Value *MemCpyArgs[] = {
+ CI->getOperand(1), CI->getOperand(2),
+ ConstantInt::get(SLC.getIntPtrType(),
+ FormatStr.size()+1), // Copy the nul byte.
+ ConstantInt::get(Type::Int32Ty, 1)
+ };
+ new CallInst(SLC.get_memcpy(), MemCpyArgs, 4, "", CI);
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(),
+ FormatStr.size()));
+ }
+
+ // The remaining optimizations require the format string to be "%s" or "%c".
+ if (FormatStr.size() != 2 || FormatStr[0] != '%')
+ return false;
+
+ // Get the second character and switch on its value
+ switch (FormatStr[1]) {
+ case 'c': {
+ // sprintf(dest,"%c",chr) -> store chr, dest
+ Value *V = CastInst::createTruncOrBitCast(CI->getOperand(3),
+ Type::Int8Ty, "char", CI);
+ new StoreInst(V, CI->getOperand(1), CI);
+ Value *Ptr = new GetElementPtrInst(CI->getOperand(1),
+ ConstantInt::get(Type::Int32Ty, 1),
+ CI->getOperand(1)->getName()+".end",
+ CI);
+ new StoreInst(ConstantInt::get(Type::Int8Ty,0), Ptr, CI);
+ return ReplaceCallWith(CI, ConstantInt::get(Type::Int32Ty, 1));
+ }
+ case 's': {
+ // sprintf(dest,"%s",str) -> llvm.memcpy(dest, str, strlen(str)+1, 1)
+ Value *Len = new CallInst(SLC.get_strlen(),
+ CastToCStr(CI->getOperand(3), CI),
+ CI->getOperand(3)->getName()+".len", CI);
+ Value *UnincLen = Len;
+ Len = BinaryOperator::createAdd(Len, ConstantInt::get(Len->getType(), 1),
+ Len->getName()+"1", CI);
+ Value *MemcpyArgs[4] = {
+ CI->getOperand(1),
+ CastToCStr(CI->getOperand(3), CI),
+ Len,
+ ConstantInt::get(Type::Int32Ty, 1)
+ };
+ new CallInst(SLC.get_memcpy(), MemcpyArgs, 4, "", CI);
+
+ // The strlen result is the unincremented number of bytes in the string.
+ if (!CI->use_empty()) {
+ if (UnincLen->getType() != CI->getType())
+ UnincLen = CastInst::createIntegerCast(UnincLen, CI->getType(), false,
+ Len->getName(), CI);
+ CI->replaceAllUsesWith(UnincLen);
+ }
+ return ReplaceCallWith(CI, 0);
+ }
+ }
+ return false;
+ }
+} SPrintFOptimizer;
+
+/// This LibCallOptimization will simplify calls to the "fputs" library
+/// function. It looks for cases where the result of fputs is not used and the
+/// operation can be reduced to something simpler.
+/// @brief Simplify the fputs library function.
+struct VISIBILITY_HIDDEN FPutsOptimization : public LibCallOptimization {
+public:
+ /// @brief Default Constructor
+ FPutsOptimization() : LibCallOptimization("fputs",
+ "Number of 'fputs' calls simplified") {}
+
+ /// @brief Make sure that the "fputs" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ // Just make sure this has 2 arguments
+ return F->arg_size() == 2;
+ }
+
+ /// @brief Perform the fputs optimization.
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // If the result is used, none of these optimizations work.
+ if (!CI->use_empty())
+ return false;
+
+ // All the optimizations depend on the length of the first argument and the
+ // fact that it is a constant string array. Check that now
+ std::string Str;
+ if (!GetConstantStringInfo(CI->getOperand(1), Str))
+ return false;
+
+ const Type *FILETy = CI->getOperand(2)->getType();
+ // fputs(s,F) -> fwrite(s,1,len,F) (if s is constant and strlen(s) > 1)
+ Value *FWriteParms[4] = {
+ CI->getOperand(1),
+ ConstantInt::get(SLC.getIntPtrType(), Str.size()),
+ ConstantInt::get(SLC.getIntPtrType(), 1),
+ CI->getOperand(2)
+ };
+ new CallInst(SLC.get_fwrite(FILETy), FWriteParms, 4, "", CI);
+ return ReplaceCallWith(CI, 0); // Known to have no uses (see above).
+ }
+} FPutsOptimizer;
+
+/// This LibCallOptimization will simplify calls to the "fwrite" function.
+struct VISIBILITY_HIDDEN FWriteOptimization : public LibCallOptimization {
+public:
+ /// @brief Default Constructor
+ FWriteOptimization() : LibCallOptimization("fwrite",
+ "Number of 'fwrite' calls simplified") {}
+
+ /// @brief Make sure that the "fputs" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ const FunctionType *FT = F->getFunctionType();
+ return FT->getNumParams() == 4 &&
+ FT->getParamType(0) == PointerType::get(Type::Int8Ty) &&
+ FT->getParamType(1) == FT->getParamType(2) &&
+ isa<IntegerType>(FT->getParamType(1)) &&
+ isa<PointerType>(FT->getParamType(3)) &&
+ isa<IntegerType>(FT->getReturnType());
+ }
+
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // Get the element size and count.
+ uint64_t EltSize, EltCount;
+ if (ConstantInt *C = dyn_cast<ConstantInt>(CI->getOperand(2)))
+ EltSize = C->getZExtValue();
+ else
+ return false;
+ if (ConstantInt *C = dyn_cast<ConstantInt>(CI->getOperand(3)))
+ EltCount = C->getZExtValue();
+ else
+ return false;
+
+ // If this is writing zero records, remove the call (it's a noop).
+ if (EltSize * EltCount == 0)
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 0));
+
+ // If this is writing one byte, turn it into fputc.
+ if (EltSize == 1 && EltCount == 1) {
+ // fwrite(s,1,1,F) -> fputc(s[0],F)
+ Value *Ptr = CI->getOperand(1);
+ Value *Val = new LoadInst(Ptr, Ptr->getName()+".byte", CI);
+ Val = new ZExtInst(Val, Type::Int32Ty, Val->getName()+".int", CI);
+ const Type *FILETy = CI->getOperand(4)->getType();
+ new CallInst(SLC.get_fputc(FILETy), Val, CI->getOperand(4), "", CI);
+ return ReplaceCallWith(CI, ConstantInt::get(CI->getType(), 1));
+ }
+ return false;
+ }
+} FWriteOptimizer;
+
+/// This LibCallOptimization will simplify calls to the "isdigit" library
+/// function. It simply does range checks the parameter explicitly.
+/// @brief Simplify the isdigit library function.
+struct VISIBILITY_HIDDEN isdigitOptimization : public LibCallOptimization {
+public:
+ isdigitOptimization() : LibCallOptimization("isdigit",
+ "Number of 'isdigit' calls simplified") {}
+
+ /// @brief Make sure that the "isdigit" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC){
+ // Just make sure this has 1 argument
+ return (f->arg_size() == 1);
+ }
+
+ /// @brief Perform the toascii optimization.
+ virtual bool OptimizeCall(CallInst *ci, SimplifyLibCalls &SLC) {
+ if (ConstantInt* CI = dyn_cast<ConstantInt>(ci->getOperand(1))) {
+ // isdigit(c) -> 0 or 1, if 'c' is constant
+ uint64_t val = CI->getZExtValue();
+ if (val >= '0' && val <= '9')
+ return ReplaceCallWith(ci, ConstantInt::get(Type::Int32Ty, 1));
+ else
+ return ReplaceCallWith(ci, ConstantInt::get(Type::Int32Ty, 0));
+ }
+
+ // isdigit(c) -> (unsigned)c - '0' <= 9
+ CastInst* cast = CastInst::createIntegerCast(ci->getOperand(1),
+ Type::Int32Ty, false/*ZExt*/, ci->getOperand(1)->getName()+".uint", ci);
+ BinaryOperator* sub_inst = BinaryOperator::createSub(cast,
+ ConstantInt::get(Type::Int32Ty,0x30),
+ ci->getOperand(1)->getName()+".sub",ci);
+ ICmpInst* setcond_inst = new ICmpInst(ICmpInst::ICMP_ULE,sub_inst,
+ ConstantInt::get(Type::Int32Ty,9),
+ ci->getOperand(1)->getName()+".cmp",ci);
+ CastInst* c2 = new ZExtInst(setcond_inst, Type::Int32Ty,
+ ci->getOperand(1)->getName()+".isdigit", ci);
+ return ReplaceCallWith(ci, c2);
+ }
+} isdigitOptimizer;
+
+struct VISIBILITY_HIDDEN isasciiOptimization : public LibCallOptimization {
+public:
+ isasciiOptimization()
+ : LibCallOptimization("isascii", "Number of 'isascii' calls simplified") {}
+
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ return F->arg_size() == 1 && F->arg_begin()->getType()->isInteger() &&
+ F->getReturnType()->isInteger();
+ }
+
+ /// @brief Perform the isascii optimization.
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+ // isascii(c) -> (unsigned)c < 128
+ Value *V = CI->getOperand(1);
+ Value *Cmp = new ICmpInst(ICmpInst::ICMP_ULT, V,
+ ConstantInt::get(V->getType(), 128),
+ V->getName()+".isascii", CI);
+ if (Cmp->getType() != CI->getType())
+ Cmp = new ZExtInst(Cmp, CI->getType(), Cmp->getName(), CI);
+ return ReplaceCallWith(CI, Cmp);
+ }
+} isasciiOptimizer;
+
+
+/// This LibCallOptimization will simplify calls to the "toascii" library
+/// function. It simply does the corresponding and operation to restrict the
+/// range of values to the ASCII character set (0-127).
+/// @brief Simplify the toascii library function.
+struct VISIBILITY_HIDDEN ToAsciiOptimization : public LibCallOptimization {
+public:
+ /// @brief Default Constructor
+ ToAsciiOptimization() : LibCallOptimization("toascii",
+ "Number of 'toascii' calls simplified") {}
+
+ /// @brief Make sure that the "fputs" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function* f, SimplifyLibCalls& SLC){
+ // Just make sure this has 2 arguments
+ return (f->arg_size() == 1);
+ }
+
+ /// @brief Perform the toascii optimization.
+ virtual bool OptimizeCall(CallInst *ci, SimplifyLibCalls &SLC) {
+ // toascii(c) -> (c & 0x7f)
+ Value *chr = ci->getOperand(1);
+ Value *and_inst = BinaryOperator::createAnd(chr,
+ ConstantInt::get(chr->getType(),0x7F),ci->getName()+".toascii",ci);
+ return ReplaceCallWith(ci, and_inst);
+ }
+} ToAsciiOptimizer;
+
+/// This LibCallOptimization will simplify calls to the "ffs" library
+/// calls which find the first set bit in an int, long, or long long. The
+/// optimization is to compute the result at compile time if the argument is
+/// a constant.
+/// @brief Simplify the ffs library function.
+struct VISIBILITY_HIDDEN FFSOptimization : public LibCallOptimization {
+protected:
+ /// @brief Subclass Constructor
+ FFSOptimization(const char* funcName, const char* description)
+ : LibCallOptimization(funcName, description) {}
+
+public:
+ /// @brief Default Constructor
+ FFSOptimization() : LibCallOptimization("ffs",
+ "Number of 'ffs' calls simplified") {}
+
+ /// @brief Make sure that the "ffs" function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ // Just make sure this has 2 arguments
+ return F->arg_size() == 1 && F->getReturnType() == Type::Int32Ty;
+ }
+
+ /// @brief Perform the ffs optimization.
+ virtual bool OptimizeCall(CallInst *TheCall, SimplifyLibCalls &SLC) {
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(TheCall->getOperand(1))) {
+ // ffs(cnst) -> bit#
+ // ffsl(cnst) -> bit#
+ // ffsll(cnst) -> bit#
+ uint64_t val = CI->getZExtValue();
+ int result = 0;
+ if (val) {
+ ++result;
+ while ((val & 1) == 0) {
+ ++result;
+ val >>= 1;
+ }
+ }
+ return ReplaceCallWith(TheCall, ConstantInt::get(Type::Int32Ty, result));
+ }
+
+ // ffs(x) -> x == 0 ? 0 : llvm.cttz(x)+1
+ // ffsl(x) -> x == 0 ? 0 : llvm.cttz(x)+1
+ // ffsll(x) -> x == 0 ? 0 : llvm.cttz(x)+1
+ const Type *ArgType = TheCall->getOperand(1)->getType();
+ const char *CTTZName;
+ assert(ArgType->getTypeID() == Type::IntegerTyID &&
+ "llvm.cttz argument is not an integer?");
+ unsigned BitWidth = cast<IntegerType>(ArgType)->getBitWidth();
+ if (BitWidth == 8)
+ CTTZName = "llvm.cttz.i8";
+ else if (BitWidth == 16)
+ CTTZName = "llvm.cttz.i16";
+ else if (BitWidth == 32)
+ CTTZName = "llvm.cttz.i32";
+ else {
+ assert(BitWidth == 64 && "Unknown bitwidth");
+ CTTZName = "llvm.cttz.i64";
+ }
+
+ Constant *F = SLC.getModule()->getOrInsertFunction(CTTZName, ArgType,
+ ArgType, NULL);
+ Value *V = CastInst::createIntegerCast(TheCall->getOperand(1), ArgType,
+ false/*ZExt*/, "tmp", TheCall);
+ Value *V2 = new CallInst(F, V, "tmp", TheCall);
+ V2 = CastInst::createIntegerCast(V2, Type::Int32Ty, false/*ZExt*/,
+ "tmp", TheCall);
+ V2 = BinaryOperator::createAdd(V2, ConstantInt::get(Type::Int32Ty, 1),
+ "tmp", TheCall);
+ Value *Cond = new ICmpInst(ICmpInst::ICMP_EQ, V,
+ Constant::getNullValue(V->getType()), "tmp",
+ TheCall);
+ V2 = new SelectInst(Cond, ConstantInt::get(Type::Int32Ty, 0), V2,
+ TheCall->getName(), TheCall);
+ return ReplaceCallWith(TheCall, V2);
+ }
+} FFSOptimizer;
+
+/// This LibCallOptimization will simplify calls to the "ffsl" library
+/// calls. It simply uses FFSOptimization for which the transformation is
+/// identical.
+/// @brief Simplify the ffsl library function.
+struct VISIBILITY_HIDDEN FFSLOptimization : public FFSOptimization {
+public:
+ /// @brief Default Constructor
+ FFSLOptimization() : FFSOptimization("ffsl",
+ "Number of 'ffsl' calls simplified") {}
+
+} FFSLOptimizer;
+
+/// This LibCallOptimization will simplify calls to the "ffsll" library
+/// calls. It simply uses FFSOptimization for which the transformation is
+/// identical.
+/// @brief Simplify the ffsl library function.
+struct VISIBILITY_HIDDEN FFSLLOptimization : public FFSOptimization {
+public:
+ /// @brief Default Constructor
+ FFSLLOptimization() : FFSOptimization("ffsll",
+ "Number of 'ffsll' calls simplified") {}
+
+} FFSLLOptimizer;
+
+/// This optimizes unary functions that take and return doubles.
+struct UnaryDoubleFPOptimizer : public LibCallOptimization {
+ UnaryDoubleFPOptimizer(const char *Fn, const char *Desc)
+ : LibCallOptimization(Fn, Desc) {}
+
+ // Make sure that this function has the right prototype
+ virtual bool ValidateCalledFunction(const Function *F, SimplifyLibCalls &SLC){
+ return F->arg_size() == 1 && F->arg_begin()->getType() == Type::DoubleTy &&
+ F->getReturnType() == Type::DoubleTy;
+ }
+
+ /// ShrinkFunctionToFloatVersion - If the input to this function is really a
+ /// float, strength reduce this to a float version of the function,
+ /// e.g. floor((double)FLT) -> (double)floorf(FLT). This can only be called
+ /// when the target supports the destination function and where there can be
+ /// no precision loss.
+ static bool ShrinkFunctionToFloatVersion(CallInst *CI, SimplifyLibCalls &SLC,
+ Constant *(SimplifyLibCalls::*FP)()){
+ if (FPExtInst *Cast = dyn_cast<FPExtInst>(CI->getOperand(1)))
+ if (Cast->getOperand(0)->getType() == Type::FloatTy) {
+ Value *New = new CallInst((SLC.*FP)(), Cast->getOperand(0),
+ CI->getName(), CI);
+ New = new FPExtInst(New, Type::DoubleTy, CI->getName(), CI);
+ CI->replaceAllUsesWith(New);
+ CI->eraseFromParent();
+ if (Cast->use_empty())
+ Cast->eraseFromParent();
+ return true;
+ }
+ return false;
+ }
+};
+
+
+struct VISIBILITY_HIDDEN FloorOptimization : public UnaryDoubleFPOptimizer {
+ FloorOptimization()
+ : UnaryDoubleFPOptimizer("floor", "Number of 'floor' calls simplified") {}
+
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+#ifdef HAVE_FLOORF
+ // If this is a float argument passed in, convert to floorf.
+ if (ShrinkFunctionToFloatVersion(CI, SLC, &SimplifyLibCalls::get_floorf))
+ return true;
+#endif
+ return false; // opt failed
+ }
+} FloorOptimizer;
+
+struct VISIBILITY_HIDDEN CeilOptimization : public UnaryDoubleFPOptimizer {
+ CeilOptimization()
+ : UnaryDoubleFPOptimizer("ceil", "Number of 'ceil' calls simplified") {}
+
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+#ifdef HAVE_CEILF
+ // If this is a float argument passed in, convert to ceilf.
+ if (ShrinkFunctionToFloatVersion(CI, SLC, &SimplifyLibCalls::get_ceilf))
+ return true;
+#endif
+ return false; // opt failed
+ }
+} CeilOptimizer;
+
+struct VISIBILITY_HIDDEN RoundOptimization : public UnaryDoubleFPOptimizer {
+ RoundOptimization()
+ : UnaryDoubleFPOptimizer("round", "Number of 'round' calls simplified") {}
+
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+#ifdef HAVE_ROUNDF
+ // If this is a float argument passed in, convert to roundf.
+ if (ShrinkFunctionToFloatVersion(CI, SLC, &SimplifyLibCalls::get_roundf))
+ return true;
+#endif
+ return false; // opt failed
+ }
+} RoundOptimizer;
+
+struct VISIBILITY_HIDDEN RintOptimization : public UnaryDoubleFPOptimizer {
+ RintOptimization()
+ : UnaryDoubleFPOptimizer("rint", "Number of 'rint' calls simplified") {}
+
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+#ifdef HAVE_RINTF
+ // If this is a float argument passed in, convert to rintf.
+ if (ShrinkFunctionToFloatVersion(CI, SLC, &SimplifyLibCalls::get_rintf))
+ return true;
+#endif
+ return false; // opt failed
+ }
+} RintOptimizer;
+
+struct VISIBILITY_HIDDEN NearByIntOptimization : public UnaryDoubleFPOptimizer {
+ NearByIntOptimization()
+ : UnaryDoubleFPOptimizer("nearbyint",
+ "Number of 'nearbyint' calls simplified") {}
+
+ virtual bool OptimizeCall(CallInst *CI, SimplifyLibCalls &SLC) {
+#ifdef HAVE_NEARBYINTF
+ // If this is a float argument passed in, convert to nearbyintf.
+ if (ShrinkFunctionToFloatVersion(CI, SLC,&SimplifyLibCalls::get_nearbyintf))
+ return true;
+#endif
+ return false; // opt failed
+ }
+} NearByIntOptimizer;
+
+/// GetConstantStringInfo - This function computes the length of a
+/// null-terminated constant array of integers. This function can't rely on the
+/// size of the constant array because there could be a null terminator in the
+/// middle of the array.
+///
+/// We also have to bail out if we find a non-integer constant initializer
+/// of one of the elements or if there is no null-terminator. The logic
+/// below checks each of these conditions and will return true only if all
+/// conditions are met. If the conditions aren't met, this returns false.
+///
+/// If successful, the \p Array param is set to the constant array being
+/// indexed, the \p Length parameter is set to the length of the null-terminated
+/// string pointed to by V, the \p StartIdx value is set to the first
+/// element of the Array that V points to, and true is returned.
+static bool GetConstantStringInfo(Value *V, std::string &Str) {
+ // Look through noop bitcast instructions.
+ if (BitCastInst *BCI = dyn_cast<BitCastInst>(V)) {
+ if (BCI->getType() == BCI->getOperand(0)->getType())
+ return GetConstantStringInfo(BCI->getOperand(0), Str);
+ return false;
+ }
+
+ // If the value is not a GEP instruction nor a constant expression with a
+ // GEP instruction, then return false because ConstantArray can't occur
+ // any other way
+ User *GEP = 0;
+ if (GetElementPtrInst *GEPI = dyn_cast<GetElementPtrInst>(V)) {
+ GEP = GEPI;
+ } else if (ConstantExpr *CE = dyn_cast<ConstantExpr>(V)) {
+ if (CE->getOpcode() != Instruction::GetElementPtr)
+ return false;
+ GEP = CE;
+ } else {
+ return false;
+ }
+
+ // Make sure the GEP has exactly three arguments.
+ if (GEP->getNumOperands() != 3)
+ return false;
+
+ // Check to make sure that the first operand of the GEP is an integer and
+ // has value 0 so that we are sure we're indexing into the initializer.
+ if (ConstantInt *Idx = dyn_cast<ConstantInt>(GEP->getOperand(1))) {
+ if (!Idx->isZero())
+ return false;
+ } else
+ return false;
+
+ // If the second index isn't a ConstantInt, then this is a variable index
+ // into the array. If this occurs, we can't say anything meaningful about
+ // the string.
+ uint64_t StartIdx = 0;
+ if (ConstantInt *CI = dyn_cast<ConstantInt>(GEP->getOperand(2)))
+ StartIdx = CI->getZExtValue();
+ else
+ return false;
+
+ // The GEP instruction, constant or instruction, must reference a global
+ // variable that is a constant and is initialized. The referenced constant
+ // initializer is the array that we'll use for optimization.
+ GlobalVariable* GV = dyn_cast<GlobalVariable>(GEP->getOperand(0));
+ if (!GV || !GV->isConstant() || !GV->hasInitializer())
+ return false;
+ Constant *GlobalInit = GV->getInitializer();
+
+ // Handle the ConstantAggregateZero case
+ if (isa<ConstantAggregateZero>(GlobalInit)) {
+ // This is a degenerate case. The initializer is constant zero so the
+ // length of the string must be zero.
+ Str.clear();
+ return true;
+ }
+
+ // Must be a Constant Array
+ ConstantArray *Array = dyn_cast<ConstantArray>(GlobalInit);
+ if (!Array) return false;
+
+ // Get the number of elements in the array
+ uint64_t NumElts = Array->getType()->getNumElements();
+
+ // Traverse the constant array from StartIdx (derived above) which is
+ // the place the GEP refers to in the array.
+ for (unsigned i = StartIdx; i < NumElts; ++i) {
+ Constant *Elt = Array->getOperand(i);
+ ConstantInt *CI = dyn_cast<ConstantInt>(Elt);
+ if (!CI) // This array isn't suitable, non-int initializer.
+ return false;
+ if (CI->isZero())
+ return true; // we found end of string, success!
+ Str += (char)CI->getZExtValue();
+ }
+
+ return false; // The array isn't null terminated.
+}
+
+/// CastToCStr - Return V if it is an sbyte*, otherwise cast it to sbyte*,
+/// inserting the cast before IP, and return the cast.
+/// @brief Cast a value to a "C" string.
+static Value *CastToCStr(Value *V, Instruction *IP) {
+ assert(isa<PointerType>(V->getType()) &&
+ "Can't cast non-pointer type to C string type");
+ const Type *SBPTy = PointerType::get(Type::Int8Ty);
+ if (V->getType() != SBPTy)
+ return new BitCastInst(V, SBPTy, V->getName(), IP);
+ return V;
+}
+
+// TODO:
+// Additional cases that we need to add to this file:
+//
+// cbrt:
+// * cbrt(expN(X)) -> expN(x/3)
+// * cbrt(sqrt(x)) -> pow(x,1/6)
+// * cbrt(sqrt(x)) -> pow(x,1/9)
+//
+// cos, cosf, cosl:
+// * cos(-x) -> cos(x)
+//
+// exp, expf, expl:
+// * exp(log(x)) -> x
+//
+// log, logf, logl:
+// * log(exp(x)) -> x
+// * log(x**y) -> y*log(x)
+// * log(exp(y)) -> y*log(e)
+// * log(exp2(y)) -> y*log(2)
+// * log(exp10(y)) -> y*log(10)
+// * log(sqrt(x)) -> 0.5*log(x)
+// * log(pow(x,y)) -> y*log(x)
+//
+// lround, lroundf, lroundl:
+// * lround(cnst) -> cnst'
+//
+// memcmp:
+// * memcmp(x,y,l) -> cnst
+// (if all arguments are constant and strlen(x) <= l and strlen(y) <= l)
+//
+// memmove:
+// * memmove(d,s,l,a) -> memcpy(d,s,l,a)
+// (if s is a global constant array)
+//
+// pow, powf, powl:
+// * pow(exp(x),y) -> exp(x*y)
+// * pow(sqrt(x),y) -> pow(x,y*0.5)
+// * pow(pow(x,y),z)-> pow(x,y*z)
+//
+// puts:
+// * puts("") -> putchar("\n")
+//
+// round, roundf, roundl:
+// * round(cnst) -> cnst'
+//
+// signbit:
+// * signbit(cnst) -> cnst'
+// * signbit(nncst) -> 0 (if pstv is a non-negative constant)
+//
+// sqrt, sqrtf, sqrtl:
+// * sqrt(expN(x)) -> expN(x*0.5)
+// * sqrt(Nroot(x)) -> pow(x,1/(2*N))
+// * sqrt(pow(x,y)) -> pow(|x|,y*0.5)
+//
+// stpcpy:
+// * stpcpy(str, "literal") ->
+// llvm.memcpy(str,"literal",strlen("literal")+1,1)
+// strrchr:
+// * strrchr(s,c) -> reverse_offset_of_in(c,s)
+// (if c is a constant integer and s is a constant string)
+// * strrchr(s1,0) -> strchr(s1,0)
+//
+// strncat:
+// * strncat(x,y,0) -> x
+// * strncat(x,y,0) -> x (if strlen(y) = 0)
+// * strncat(x,y,l) -> strcat(x,y) (if y and l are constants an l > strlen(y))
+//
+// strncpy:
+// * strncpy(d,s,0) -> d
+// * strncpy(d,s,l) -> memcpy(d,s,l,1)
+// (if s and l are constants)
+//
+// strpbrk:
+// * strpbrk(s,a) -> offset_in_for(s,a)
+// (if s and a are both constant strings)
+// * strpbrk(s,"") -> 0
+// * strpbrk(s,a) -> strchr(s,a[0]) (if a is constant string of length 1)
+//
+// strspn, strcspn:
+// * strspn(s,a) -> const_int (if both args are constant)
+// * strspn("",a) -> 0
+// * strspn(s,"") -> 0
+// * strcspn(s,a) -> const_int (if both args are constant)
+// * strcspn("",a) -> 0
+// * strcspn(s,"") -> strlen(a)
+//
+// strstr:
+// * strstr(x,x) -> x
+// * strstr(s1,s2) -> offset_of_s2_in(s1)
+// (if s1 and s2 are constant strings)
+//
+// tan, tanf, tanl:
+// * tan(atan(x)) -> x
+//
+// trunc, truncf, truncl:
+// * trunc(cnst) -> cnst'
+//
+//
+}
diff --git a/lib/Transforms/IPO/StripDeadPrototypes.cpp b/lib/Transforms/IPO/StripDeadPrototypes.cpp
new file mode 100644
index 0000000..9851b26
--- /dev/null
+++ b/lib/Transforms/IPO/StripDeadPrototypes.cpp
@@ -0,0 +1,70 @@
+//===-- StripDeadPrototypes.cpp - Removed unused function declarations ----===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file was developed by Reid Spencer and is distributed under the
+// University of Illinois Open Source License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This pass loops over all of the functions in the input module, looking for
+// dead declarations and removes them.
+//
+//===----------------------------------------------------------------------===//
+
+#define DEBUG_TYPE "strip-dead-prototypes"
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Pass.h"
+#include "llvm/Module.h"
+#include "llvm/ADT/Statistic.h"
+#include "llvm/Support/Compiler.h"
+using namespace llvm;
+
+STATISTIC(NumDeadPrototypes, "Number of dead prototypes removed");
+
+namespace {
+
+/// @brief Pass to remove unused function declarations.
+class VISIBILITY_HIDDEN StripDeadPrototypesPass : public ModulePass {
+public:
+ static char ID; // Pass identification, replacement for typeid
+ StripDeadPrototypesPass() : ModulePass((intptr_t)&ID) { }
+ virtual bool runOnModule(Module &M);
+};
+
+char StripDeadPrototypesPass::ID = 0;
+RegisterPass<StripDeadPrototypesPass> X("strip-dead-prototypes",
+ "Strip Unused Function Prototypes");
+
+} // end anonymous namespace
+
+bool StripDeadPrototypesPass::runOnModule(Module &M) {
+ bool MadeChange = false;
+
+ // Erase dead function prototypes.
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ) {
+ Function *F = I++;
+ // Function must be a prototype and unused.
+ if (F->isDeclaration() && F->use_empty()) {
+ F->eraseFromParent();
+ ++NumDeadPrototypes;
+ MadeChange = true;
+ }
+ }
+
+ // Erase dead global var prototypes.
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ) {
+ GlobalVariable *GV = I++;
+ // Global must be a prototype and unused.
+ if (GV->isDeclaration() && GV->use_empty())
+ GV->eraseFromParent();
+ }
+
+ // Return an indication of whether we changed anything or not.
+ return MadeChange;
+}
+
+ModulePass *llvm::createStripDeadPrototypesPass() {
+ return new StripDeadPrototypesPass();
+}
diff --git a/lib/Transforms/IPO/StripSymbols.cpp b/lib/Transforms/IPO/StripSymbols.cpp
new file mode 100644
index 0000000..c8f8926
--- /dev/null
+++ b/lib/Transforms/IPO/StripSymbols.cpp
@@ -0,0 +1,206 @@
+//===- StripSymbols.cpp - Strip symbols and debug info from a module ------===//
+//
+// 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 implements stripping symbols out of symbol tables.
+//
+// Specifically, this allows you to strip all of the symbols out of:
+// * All functions in a module
+// * All non-essential symbols in a module (all function symbols + all module
+// scope symbols)
+// * Debug information.
+//
+// Notice that:
+// * This pass makes code much less readable, so it should only be used in
+// situations where the 'strip' utility would be used (such as reducing
+// code size, and making it harder to reverse engineer code).
+//
+//===----------------------------------------------------------------------===//
+
+#include "llvm/Transforms/IPO.h"
+#include "llvm/Constants.h"
+#include "llvm/DerivedTypes.h"
+#include "llvm/Instructions.h"
+#include "llvm/Module.h"
+#include "llvm/Pass.h"
+#include "llvm/ValueSymbolTable.h"
+#include "llvm/TypeSymbolTable.h"
+#include "llvm/Support/Compiler.h"
+using namespace llvm;
+
+namespace {
+ class VISIBILITY_HIDDEN StripSymbols : public ModulePass {
+ bool OnlyDebugInfo;
+ public:
+ static char ID; // Pass identification, replacement for typeid
+ StripSymbols(bool ODI = false)
+ : ModulePass((intptr_t)&ID), OnlyDebugInfo(ODI) {}
+
+ virtual bool runOnModule(Module &M);
+
+ virtual void getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ }
+ };
+
+ char StripSymbols::ID = 0;
+ RegisterPass<StripSymbols> X("strip", "Strip all symbols from a module");
+}
+
+ModulePass *llvm::createStripSymbolsPass(bool OnlyDebugInfo) {
+ return new StripSymbols(OnlyDebugInfo);
+}
+
+static void RemoveDeadConstant(Constant *C) {
+ assert(C->use_empty() && "Constant is not dead!");
+ std::vector<Constant*> Operands;
+ for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i)
+ if (isa<DerivedType>(C->getOperand(i)->getType()) &&
+ C->getOperand(i)->hasOneUse())
+ Operands.push_back(C->getOperand(i));
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(C)) {
+ if (!GV->hasInternalLinkage()) return; // Don't delete non static globals.
+ GV->eraseFromParent();
+ }
+ else if (!isa<Function>(C))
+ C->destroyConstant();
+
+ // If the constant referenced anything, see if we can delete it as well.
+ while (!Operands.empty()) {
+ RemoveDeadConstant(Operands.back());
+ Operands.pop_back();
+ }
+}
+
+// Strip the symbol table of its names.
+//
+static void StripSymtab(ValueSymbolTable &ST) {
+ for (ValueSymbolTable::iterator VI = ST.begin(), VE = ST.end(); VI != VE; ) {
+ Value *V = VI->getValue();
+ ++VI;
+ if (!isa<GlobalValue>(V) || cast<GlobalValue>(V)->hasInternalLinkage()) {
+ // Set name to "", removing from symbol table!
+ V->setName("");
+ }
+ }
+}
+
+// Strip the symbol table of its names.
+static void StripTypeSymtab(TypeSymbolTable &ST) {
+ for (TypeSymbolTable::iterator TI = ST.begin(), E = ST.end(); TI != E; )
+ ST.remove(TI++);
+}
+
+
+
+bool StripSymbols::runOnModule(Module &M) {
+ // If we're not just stripping debug info, strip all symbols from the
+ // functions and the names from any internal globals.
+ if (!OnlyDebugInfo) {
+ for (Module::global_iterator I = M.global_begin(), E = M.global_end();
+ I != E; ++I)
+ if (I->hasInternalLinkage())
+ I->setName(""); // Internal symbols can't participate in linkage
+
+ for (Module::iterator I = M.begin(), E = M.end(); I != E; ++I) {
+ if (I->hasInternalLinkage())
+ I->setName(""); // Internal symbols can't participate in linkage
+ StripSymtab(I->getValueSymbolTable());
+ }
+
+ // Remove all names from types.
+ StripTypeSymtab(M.getTypeSymbolTable());
+ }
+
+ // Strip debug info in the module if it exists. To do this, we remove
+ // llvm.dbg.func.start, llvm.dbg.stoppoint, and llvm.dbg.region.end calls, and
+ // any globals they point to if now dead.
+ Function *FuncStart = M.getFunction("llvm.dbg.func.start");
+ Function *StopPoint = M.getFunction("llvm.dbg.stoppoint");
+ Function *RegionStart = M.getFunction("llvm.dbg.region.start");
+ Function *RegionEnd = M.getFunction("llvm.dbg.region.end");
+ Function *Declare = M.getFunction("llvm.dbg.declare");
+ if (!FuncStart && !StopPoint && !RegionStart && !RegionEnd && !Declare)
+ return true;
+
+ std::vector<GlobalVariable*> DeadGlobals;
+
+ // Remove all of the calls to the debugger intrinsics, and remove them from
+ // the module.
+ if (FuncStart) {
+ while (!FuncStart->use_empty()) {
+ CallInst *CI = cast<CallInst>(FuncStart->use_back());
+ Value *Arg = CI->getOperand(1);
+ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
+ CI->eraseFromParent();
+ if (Arg->use_empty())
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
+ DeadGlobals.push_back(GV);
+ }
+ FuncStart->eraseFromParent();
+ }
+ if (StopPoint) {
+ while (!StopPoint->use_empty()) {
+ CallInst *CI = cast<CallInst>(StopPoint->use_back());
+ Value *Arg = CI->getOperand(3);
+ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
+ CI->eraseFromParent();
+ if (Arg->use_empty())
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
+ DeadGlobals.push_back(GV);
+ }
+ StopPoint->eraseFromParent();
+ }
+ if (RegionStart) {
+ while (!RegionStart->use_empty()) {
+ CallInst *CI = cast<CallInst>(RegionStart->use_back());
+ Value *Arg = CI->getOperand(1);
+ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
+ CI->eraseFromParent();
+ if (Arg->use_empty())
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
+ DeadGlobals.push_back(GV);
+ }
+ RegionStart->eraseFromParent();
+ }
+ if (RegionEnd) {
+ while (!RegionEnd->use_empty()) {
+ CallInst *CI = cast<CallInst>(RegionEnd->use_back());
+ Value *Arg = CI->getOperand(1);
+ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
+ CI->eraseFromParent();
+ if (Arg->use_empty())
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
+ DeadGlobals.push_back(GV);
+ }
+ RegionEnd->eraseFromParent();
+ }
+ if (Declare) {
+ while (!Declare->use_empty()) {
+ CallInst *CI = cast<CallInst>(Declare->use_back());
+ Value *Arg = CI->getOperand(2);
+ assert(CI->use_empty() && "llvm.dbg intrinsic should have void result");
+ CI->eraseFromParent();
+ if (Arg->use_empty())
+ if (GlobalVariable *GV = dyn_cast<GlobalVariable>(Arg))
+ DeadGlobals.push_back(GV);
+ }
+ Declare->eraseFromParent();
+ }
+
+ // Finally, delete any internal globals that were only used by the debugger
+ // intrinsics.
+ while (!DeadGlobals.empty()) {
+ GlobalVariable *GV = DeadGlobals.back();
+ DeadGlobals.pop_back();
+ if (GV->hasInternalLinkage())
+ RemoveDeadConstant(GV);
+ }
+
+ return true;
+}