Change over to use new style pass mechanism, now passes only expose small

creation functions in their public header file, unless they can help it.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@1816 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2002-02-26 21:46:54 +00:00
parent 3b2541424f
commit bd0ef77cde
32 changed files with 528 additions and 512 deletions

View File

@ -10,51 +10,10 @@
#ifndef LLVM_TRANSFORMS_CHANGEALLOCATIONS_H #ifndef LLVM_TRANSFORMS_CHANGEALLOCATIONS_H
#define LLVM_TRANSFORMS_CHANGEALLOCATIONS_H #define LLVM_TRANSFORMS_CHANGEALLOCATIONS_H
#include "llvm/Pass.h" class Pass;
class TargetData; class TargetData;
// LowerAllocations - Turn malloc and free instructions into %malloc and %free Pass *createLowerAllocationsPass(const TargetData &TD);
// calls. Pass *createRaiseAllocationsPass();
//
class LowerAllocations : public BasicBlockPass {
Method *MallocMeth; // Methods in the module we are processing
Method *FreeMeth; // Initialized by doInitialization
const TargetData &DataLayout;
public:
inline LowerAllocations(const TargetData &TD) : DataLayout(TD) {
MallocMeth = FreeMeth = 0;
}
// doPassInitialization - For the lower allocations pass, this ensures that a
// module contains a declaration for a malloc and a free function.
//
bool doInitialization(Module *M);
// runOnBasicBlock - This method does the actual work of converting
// instructions over, assuming that the pass has already been initialized.
//
bool runOnBasicBlock(BasicBlock *BB);
};
// RaiseAllocations - Turn %malloc and %free calls into the appropriate
// instruction.
//
class RaiseAllocations : public BasicBlockPass {
Method *MallocMeth; // Methods in the module we are processing
Method *FreeMeth; // Initialized by doPassInitializationVirt
public:
inline RaiseAllocations() : MallocMeth(0), FreeMeth(0) {}
// doPassInitialization - For the raise allocations pass, this finds a
// declaration for malloc and free if they exist.
//
bool doInitialization(Module *M);
// runOnBasicBlock - This method does the actual work of converting
// instructions over, assuming that the pass has already been initialized.
//
bool runOnBasicBlock(BasicBlock *BB);
};
#endif #endif

View File

@ -4,23 +4,14 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_OPT_METHOD_INLINING_H #ifndef LLVM_TRANSFORMS_METHOD_INLINING_H
#define LLVM_OPT_METHOD_INLINING_H #define LLVM_TRANSFORMS_METHOD_INLINING_H
#include "llvm/Pass.h"
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
class CallInst; class CallInst;
class Pass;
struct MethodInlining : public MethodPass { Pass *createMethodInliningPass();
// DoMethodInlining - Use a heuristic based approach to inline methods that
// seem to look good.
//
static bool doMethodInlining(Method *M);
virtual bool runOnMethod(Method *M) {
return doMethodInlining(M);
}
};
// InlineMethod - This function forcibly inlines the called method into the // InlineMethod - This function forcibly inlines the called method into the
// basic block of the caller. This returns true if it is not possible to inline // basic block of the caller. This returns true if it is not possible to inline

View File

@ -9,14 +9,7 @@
#ifndef LLVM_TRANSFORMS_HOISTPHICONSTANTS_H #ifndef LLVM_TRANSFORMS_HOISTPHICONSTANTS_H
#define LLVM_TRANSFORMS_HOISTPHICONSTANTS_H #define LLVM_TRANSFORMS_HOISTPHICONSTANTS_H
#include "llvm/Pass.h" class Pass;
Pass *createHoistPHIConstantsPass();
struct HoistPHIConstants : public MethodPass {
// doHoistPHIConstants - Hoist constants out of PHI instructions
//
static bool doHoistPHIConstants(Method *M);
virtual bool runOnMethod(Method *M) { return doHoistPHIConstants(M); }
};
#endif #endif

View File

@ -6,35 +6,7 @@
#ifndef LLVM_TRANSFORMS_CLEANUPGCCOUTPUT_H #ifndef LLVM_TRANSFORMS_CLEANUPGCCOUTPUT_H
#define LLVM_TRANSFORMS_CLEANUPGCCOUTPUT_H #define LLVM_TRANSFORMS_CLEANUPGCCOUTPUT_H
#include "llvm/Pass.h" class Pass;
Pass *createCleanupGCCOutputPass();
struct CleanupGCCOutput : public MethodPass {
// PatchUpMethodReferences - This is a part of the functionality exported by
// the CleanupGCCOutput pass. This causes functions with different signatures
// to be linked together if they have the same name.
//
static bool PatchUpMethodReferences(Module *M);
// 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 doInitialization(Module *M);
// doPerMethodWork - This method simplifies the specified method hopefully.
//
bool runOnMethod(Method *M);
// doPassFinalization - Strip out type names that are unused by the program
bool doFinalization(Module *M);
// getAnalysisUsageInfo - This function needs FindUsedTypes to do its job...
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided);
};
#endif #endif

View File

@ -17,44 +17,8 @@
#ifndef LLVM_TRANSFORMS_CONSTANTMERGE_H #ifndef LLVM_TRANSFORMS_CONSTANTMERGE_H
#define LLVM_TRANSFORMS_CONSTANTMERGE_H #define LLVM_TRANSFORMS_CONSTANTMERGE_H
#include "llvm/Pass.h" class Pass;
class Constant; Pass *createConstantMergePass();
class GlobalVariable; Pass *createDynamicConstantMergePass();
// FIXME: ConstantMerge should not be a methodPass!!!
class ConstantMerge : public MethodPass {
protected:
std::map<Constant*, GlobalVariable*> Constants;
unsigned LastConstantSeen;
public:
inline ConstantMerge() : LastConstantSeen(0) {}
// mergeDuplicateConstants - Static accessor for clients that don't want to
// deal with passes.
//
static bool mergeDuplicateConstants(Module *M);
// doInitialization - For this pass, process all of the globals in the
// module, eliminating duplicate constants.
//
bool doInitialization(Module *M);
bool runOnMethod(Method*) { return false; }
// doFinalization - Clean up internal state for this module
//
bool doFinalization(Module *M) {
LastConstantSeen = 0;
Constants.clear();
return false;
}
};
struct DynamicConstantMerge : public ConstantMerge {
// doPerMethodWork - Check to see if any globals have been added to the
// global list for the module. If so, eliminate them.
//
bool runOnMethod(Method *M);
};
#endif #endif

View File

@ -7,25 +7,7 @@
#ifndef LLVM_TRANSFORM_IPO_GLOBALDCE_H #ifndef LLVM_TRANSFORM_IPO_GLOBALDCE_H
#define LLVM_TRANSFORM_IPO_GLOBALDCE_H #define LLVM_TRANSFORM_IPO_GLOBALDCE_H
#include "llvm/Pass.h" class Pass;
Pass *createGlobalDCEPass();
namespace cfg { class CallGraph; }
class Module;
struct GlobalDCE : public Pass {
// run - Do the GlobalDCE pass on the specified module, optionally updating
// the specified callgraph to reflect the changes.
//
bool run(Module *M);
// getAnalysisUsageInfo - This function works on the call graph of a module.
// It is capable of updating the call graph to reflect the new state of the
// module.
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided);
};
#endif #endif

View File

@ -8,30 +8,8 @@
#ifndef LLVM_TRANSFORMS_SIMPLESTRUCTMUTATION_H #ifndef LLVM_TRANSFORMS_SIMPLESTRUCTMUTATION_H
#define LLVM_TRANSFORMS_SIMPLESTRUCTMUTATION_H #define LLVM_TRANSFORMS_SIMPLESTRUCTMUTATION_H
#include "llvm/Transforms/IPO/MutateStructTypes.h" class Pass;
Pass *createSwapElementsPass();
class SimpleStructMutation : public MutateStructTypes { Pass *createSortElementsPass();
public:
enum Transform { SwapElements, SortElements } CurrentXForm;
SimpleStructMutation(enum Transform XForm) : CurrentXForm(XForm) {}
virtual bool run(Module *M) {
setTransforms(getTransforms(M, CurrentXForm));
bool Changed = MutateStructTypes::run(M);
clearTransforms();
return Changed;
}
// getAnalysisUsageInfo - This function needs the results of the
// FindUsedTypes and FindUnsafePointerTypes analysis passes...
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided);
private:
TransformsType getTransforms(Module *M, enum Transform);
};
#endif #endif

View File

@ -8,35 +8,8 @@
#ifndef LLVM_TRANSFORMS_INSTRUMENTATION_TRACEVALUES_H #ifndef LLVM_TRANSFORMS_INSTRUMENTATION_TRACEVALUES_H
#define LLVM_TRANSFORMS_INSTRUMENTATION_TRACEVALUES_H #define LLVM_TRANSFORMS_INSTRUMENTATION_TRACEVALUES_H
#include "llvm/Pass.h" class Pass;
class Method; Pass *createTraceValuesPassForMethod(); // Just trace methods
Pass *createTraceValuesPassForBasicBlocks(); // Trace BB's and methods
class InsertTraceCode : public MethodPass {
bool TraceBasicBlockExits, TraceMethodExits;
Method *PrintfMeth;
public:
InsertTraceCode(bool traceBasicBlockExits, bool traceMethodExits)
: TraceBasicBlockExits(traceBasicBlockExits),
TraceMethodExits(traceMethodExits) {}
// Add a prototype for printf if it is not already in the program.
//
bool doInitialization(Module *M);
//--------------------------------------------------------------------------
// Function InsertCodeToTraceValues
//
// Inserts tracing code for all live values at basic block and/or method exits
// as specified by `traceBasicBlockExits' and `traceMethodExits'.
//
static bool doit(Method *M, bool traceBasicBlockExits,
bool traceMethodExits, Method *Printf);
// runOnMethod - This method does the work. Always successful.
//
bool runOnMethod(Method *M) {
return doit(M, TraceBasicBlockExits, TraceMethodExits, PrintfMeth);
}
};
#endif #endif

View File

@ -9,27 +9,12 @@
#ifndef LLVM_TRANSFORMS_LEVELCHANGE_H #ifndef LLVM_TRANSFORMS_LEVELCHANGE_H
#define LLVM_TRANSFORMS_LEVELCHANGE_H #define LLVM_TRANSFORMS_LEVELCHANGE_H
#include "llvm/Pass.h" class Pass;
// RaisePointerReferences - Try to eliminate as many pointer arithmetic // RaisePointerReferences - Try to eliminate as many pointer arithmetic
// expressions as possible, by converting expressions to use getelementptr and // expressions as possible, by converting expressions to use getelementptr and
// friends. // friends.
// //
struct RaisePointerReferences : public MethodPass { Pass *createRaisePointerReferencesPass();
static bool doit(Method *M);
virtual bool runOnMethod(Method *M) { return doit(M); }
};
// EliminateAuxillaryInductionVariables - Eliminate all aux indvars. This
// converts all induction variables to reference a cannonical induction
// variable (which starts at 0 and counts by 1).
//
struct EliminateAuxillaryInductionVariables : public MethodPass {
static bool doit(Method *M) { return false; } // TODO!
virtual bool runOnMethod(Method *M) { return doit(M); }
};
#endif #endif

View File

@ -7,26 +7,19 @@
#ifndef LLVM_TRANSFORMS_SCALAR_CONSTANT_PROPOGATION_H #ifndef LLVM_TRANSFORMS_SCALAR_CONSTANT_PROPOGATION_H
#define LLVM_TRANSFORMS_SCALAR_CONSTANT_PROPOGATION_H #define LLVM_TRANSFORMS_SCALAR_CONSTANT_PROPOGATION_H
#include "llvm/Pass.h"
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
class TerminatorInst; class TerminatorInst;
class Pass;
struct ConstantPropogation : public MethodPass { //===----------------------------------------------------------------------===//
// doConstantPropogation - Do trivial constant propogation and expression // Normal Constant Propogation Pass
// folding //
static bool doConstantPropogation(Method *M); Pass *createConstantPropogationPass();
// doConstantPropogation - Constant prop a specific instruction. Returns true
// and potentially moves the iterator if constant propogation was performed.
//
static bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &I);
inline bool runOnMethod(Method *M) {
return doConstantPropogation(M);
}
};
// doConstantPropogation - Constant prop a specific instruction. Returns true
// and potentially moves the iterator if constant propogation was performed.
//
bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &I);
// ConstantFoldTerminator - If a terminator instruction is predicated on a // ConstantFoldTerminator - If a terminator instruction is predicated on a
// constant value, convert it into an unconditional branch to the constant // constant value, convert it into an unconditional branch to the constant
@ -38,12 +31,6 @@ bool ConstantFoldTerminator(TerminatorInst *T);
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Sparse Conditional Constant Propogation Pass // Sparse Conditional Constant Propogation Pass
// //
struct SCCPPass : public MethodPass { Pass *createSCCPPass();
static bool doSCCP(Method *M);
inline bool runOnMethod(Method *M) {
return doSCCP(M);
}
};
#endif #endif

View File

@ -5,21 +5,19 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_OPT_DCE_H #ifndef LLVM_TRANSFORMS_SCALAR_DCE_H
#define LLVM_OPT_DCE_H #define LLVM_TRANSFORMS_SCALAR_DCE_H
#include "llvm/Pass.h"
#include "llvm/Method.h" #include "llvm/Method.h"
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
class Pass;
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// DeadInstElimination - This pass quickly removes trivially dead instructions // DeadInstElimination - This pass quickly removes trivially dead instructions
// without modifying the CFG of the function. It is a BasicBlockPass, so it // without modifying the CFG of the function. It is a BasicBlockPass, so it
// runs efficiently when queued next to other BasicBlockPass's. // runs efficiently when queued next to other BasicBlockPass's.
// //
struct DeadInstElimination : public BasicBlockPass { Pass *createDeadInstEliminationPass();
virtual bool runOnBasicBlock(BasicBlock *BB);
};
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
@ -32,34 +30,16 @@ struct DeadInstElimination : public BasicBlockPass {
// otherwise simplifies control flow. This should be factored out of this pass // otherwise simplifies control flow. This should be factored out of this pass
// eventually into it's own pass. // eventually into it's own pass.
// //
struct DeadCodeElimination : public MethodPass {
// External Interface:
//
static bool doDCE(Method *M);
// dceInstruction - Inspect the instruction at *BBI and figure out if it's Pass *createDeadCodeEliminationPass();
// [trivially] dead. If so, remove the instruction and update the iterator
// to point to the instruction that immediately succeeded the original
// instruction.
//
static bool dceInstruction(BasicBlock::InstListType &BBIL,
BasicBlock::iterator &BBI);
// Remove unused global values - This removes unused global values of no // dceInstruction - Inspect the instruction at *BBI and figure out if it's
// possible value. This currently includes unused method prototypes and // [trivially] dead. If so, remove the instruction and update the iterator
// unitialized global variables. // to point to the instruction that immediately succeeded the original
// // instruction.
static bool RemoveUnusedGlobalValues(Module *M); //
bool dceInstruction(BasicBlock::InstListType &BBIL,
// Pass Interface... BasicBlock::iterator &BBI);
virtual bool doInitialization(Module *M) {
return RemoveUnusedGlobalValues(M);
}
virtual bool runOnMethod(Method *M) { return doDCE(M); }
virtual bool doFinalization(Module *M) {
return RemoveUnusedGlobalValues(M);
}
};
@ -68,15 +48,7 @@ struct DeadCodeElimination : public MethodPass {
// algorithm assumes instructions are dead until proven otherwise, which makes // algorithm assumes instructions are dead until proven otherwise, which makes
// it more successful are removing non-obviously dead instructions. // it more successful are removing non-obviously dead instructions.
// //
struct AgressiveDCE : public MethodPass { Pass *createAgressiveDCEPass();
virtual bool runOnMethod(Method *M);
// getAnalysisUsageInfo - We require post dominance frontiers (aka Control
// Dependence Graph)
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided);
};
// SimplifyCFG - This function is used to do simplification of a CFG. For // SimplifyCFG - This function is used to do simplification of a CFG. For

View File

@ -8,18 +8,7 @@
#ifndef LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H #ifndef LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H
#define LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H #define LLVM_TRANSFORMS_SCALAR_INDVARSIMPLIFY_H
#include "llvm/Pass.h" class Pass;
Pass *createIndVarSimplifyPass();
namespace cfg { class LoopInfo; }
struct InductionVariableSimplify : public MethodPass {
static bool doit(Method *M, cfg::LoopInfo &Loops);
virtual bool runOnMethod(Method *M);
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided);
};
#endif #endif

View File

@ -15,14 +15,7 @@
#ifndef LLVM_TRANSFORMS_SCALAR_INSTRUCTIONCOMBINING_H #ifndef LLVM_TRANSFORMS_SCALAR_INSTRUCTIONCOMBINING_H
#define LLVM_TRANSFORMS_SCALAR_INSTRUCTIONCOMBINING_H #define LLVM_TRANSFORMS_SCALAR_INSTRUCTIONCOMBINING_H
#include "llvm/Pass.h" class Pass;
class Instruction; Pass *createInstructionCombiningPass();
struct InstructionCombining : public MethodPass {
static bool doit(Method *M);
static bool CombineInstruction(Instruction *I);
virtual bool runOnMethod(Method *M) { return doit(M); }
};
#endif #endif

View File

@ -5,35 +5,12 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef LLVM_OPT_SYMBOL_STRIPPING_H #ifndef LLVM_TRANSFORMS_SYMBOL_STRIPPING_H
#define LLVM_OPT_SYMBOL_STRIPPING_H #define LLVM_TRANSFORMS_SYMBOL_STRIPPING_H
#include "llvm/Pass.h" class Pass;
struct SymbolStripping : public MethodPass { Pass *createSymbolStrippingPass();
// doSymbolStripping - Remove all symbolic information from a method Pass *createFullSymbolStrippingPass();
//
static bool doSymbolStripping(Method *M);
virtual bool runOnMethod(Method *M) {
return doSymbolStripping(M);
}
};
struct FullSymbolStripping : public MethodPass {
// doStripGlobalSymbols - Remove all symbolic information from all methods
// in a module, and all module level symbols. (method names, etc...)
//
static bool doStripGlobalSymbols(Module *M);
virtual bool doInitialization(Module *M) {
return doStripGlobalSymbols(M);
}
virtual bool runOnMethod(Method *M) {
return SymbolStripping::doSymbolStripping(M);
}
};
#endif #endif

View File

@ -40,4 +40,8 @@ public:
} }
}; };
static inline Pass *createUnifyMethodExitNodesPass() {
return new UnifyMethodExitNodes();
}
#endif #endif

View File

@ -11,6 +11,7 @@
#include "llvm/iOther.h" #include "llvm/iOther.h"
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
#include "llvm/Method.h" #include "llvm/Method.h"
#include "llvm/Pass.h"
#include <map> #include <map>
#include <vector> #include <vector>
@ -19,12 +20,6 @@ typedef std::map<BBConstTy, CastInst *> CachedCopyMap;
static Value *NormalizePhiOperand(PHINode *PN, Value *CPV, static Value *NormalizePhiOperand(PHINode *PN, Value *CPV,
BasicBlock *Pred, CachedCopyMap &CopyCache) { BasicBlock *Pred, CachedCopyMap &CopyCache) {
/* NOTE: CahedCopyMap was disabled to insert phi elimination code
for all phi args -- Ruchira
*/
// Check if we've already inserted a copy for this constant in Pred // Check if we've already inserted a copy for this constant in Pred
// Note that `copyCache[Pred]' will create an empty vector the first time // Note that `copyCache[Pred]' will create an empty vector the first time
// //
@ -47,7 +42,7 @@ static Value *NormalizePhiOperand(PHINode *PN, Value *CPV,
// Entry point for normalizing constant args in PHIs // Entry point for normalizing constant args in PHIs
//--------------------------------------------------------------------------- //---------------------------------------------------------------------------
bool HoistPHIConstants::doHoistPHIConstants(Method *M) { static bool doHoistPHIConstants(Method *M) {
CachedCopyMap Cache; CachedCopyMap Cache;
bool Changed = false; bool Changed = false;
@ -77,3 +72,11 @@ bool HoistPHIConstants::doHoistPHIConstants(Method *M) {
return Changed; return Changed;
} }
namespace {
struct HoistPHIConstants : public MethodPass {
virtual bool runOnMethod(Method *M) { return doHoistPHIConstants(M); }
};
}
Pass *createHoistPHIConstantsPass() { return new HoistPHIConstants(); }

View File

@ -18,6 +18,7 @@
#include "llvm/GlobalVariable.h" #include "llvm/GlobalVariable.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/Method.h" #include "llvm/Method.h"
#include "llvm/Pass.h"
// mergeDuplicateConstants - Workhorse for the pass. This eliminates duplicate // mergeDuplicateConstants - Workhorse for the pass. This eliminates duplicate
// constants, starting at global ConstantNo, and adds vars to the map if they // constants, starting at global ConstantNo, and adds vars to the map if they
@ -56,27 +57,43 @@ bool mergeDuplicateConstants(Module *M, unsigned &ConstantNo,
return MadeChanges; return MadeChanges;
} }
namespace {
// mergeDuplicateConstants - Static accessor for clients that don't want to // FIXME: ConstantMerge should not be a methodPass!!!
// deal with passes. class ConstantMerge : public MethodPass {
// protected:
bool ConstantMerge::mergeDuplicateConstants(Module *M) { std::map<Constant*, GlobalVariable*> Constants;
std::map<Constant*, GlobalVariable*> Constants; unsigned LastConstantSeen;
unsigned LastConstantSeen = 0; public:
return ::mergeDuplicateConstants(M, LastConstantSeen, Constants); inline ConstantMerge() : LastConstantSeen(0) {}
// doInitialization - For this pass, process all of the globals in the
// module, eliminating duplicate constants.
//
bool doInitialization(Module *M) {
return ::mergeDuplicateConstants(M, LastConstantSeen, Constants);
}
bool runOnMethod(Method*) { return false; }
// doFinalization - Clean up internal state for this module
//
bool doFinalization(Module *M) {
LastConstantSeen = 0;
Constants.clear();
return false;
}
};
struct DynamicConstantMerge : public ConstantMerge {
// doPerMethodWork - Check to see if any globals have been added to the
// global list for the module. If so, eliminate them.
//
bool runOnMethod(Method *M) {
return ::mergeDuplicateConstants(M->getParent(), LastConstantSeen,
Constants);
}
};
} }
Pass *createConstantMergePass() { return new ConstantMerge(); }
// doInitialization - For this pass, process all of the globals in the Pass *createDynamicConstantMergePass() { return new DynamicConstantMerge(); }
// module, eliminating duplicate constants.
//
bool ConstantMerge::doInitialization(Module *M) {
return ::mergeDuplicateConstants(M, LastConstantSeen, Constants);
}
// doPerMethodWork - Check to see if any globals have been added to the
// global list for the module. If so, eliminate them.
//
bool DynamicConstantMerge::runOnMethod(Method *M) {
return ::mergeDuplicateConstants(M->getParent(), LastConstantSeen, Constants);
}

View File

@ -23,6 +23,7 @@
#include "llvm/iTerminators.h" #include "llvm/iTerminators.h"
#include "llvm/iOther.h" #include "llvm/iOther.h"
#include "llvm/Support/CFG.h" #include "llvm/Support/CFG.h"
#include "llvm/Pass.h"
#include <algorithm> #include <algorithm>
#include <iostream> #include <iostream>
using std::vector; using std::vector;
@ -31,6 +32,36 @@ using std::cerr;
static const Type *PtrSByte = 0; // 'sbyte*' type static const Type *PtrSByte = 0; // 'sbyte*' type
namespace {
struct CleanupGCCOutput : public MethodPass {
// 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 doInitialization(Module *M);
// doPerMethodWork - This method simplifies the specified method hopefully.
//
bool runOnMethod(Method *M);
// doPassFinalization - Strip out type names that are unused by the program
bool doFinalization(Module *M);
// getAnalysisUsageInfo - This function needs FindUsedTypes to do its job...
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
// FIXME: Invalidates the CFG
Required.push_back(FindUsedTypes::ID);
}
};
}
// ConvertCallTo - Convert a call to a varargs function with no arg types // ConvertCallTo - Convert a call to a varargs function with no arg types
// specified to a concrete nonvarargs method. // specified to a concrete nonvarargs method.
// //
@ -79,7 +110,7 @@ static void ConvertCallTo(CallInst *CI, Method *Dest) {
// because of the way things are declared in C. If this is the case, patch // because of the way things are declared in C. If this is the case, patch
// things up. // things up.
// //
bool CleanupGCCOutput::PatchUpMethodReferences(Module *M) { static bool PatchUpMethodReferences(Module *M) {
SymbolTable *ST = M->getSymbolTable(); SymbolTable *ST = M->getSymbolTable();
if (!ST) return false; if (!ST) return false;
@ -545,12 +576,7 @@ bool CleanupGCCOutput::doFinalization(Module *M) {
return Changed; return Changed;
} }
// getAnalysisUsageInfo - This function needs the results of the Pass *createCleanupGCCOutputPass() {
// FindUsedTypes and FindUnsafePointerTypes analysis passes... return new CleanupGCCOutput();
//
void CleanupGCCOutput::getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
// FIXME: Invalidates the CFG
Required.push_back(FindUsedTypes::ID);
} }

View File

@ -8,6 +8,7 @@
#include "llvm/Analysis/CallGraph.h" #include "llvm/Analysis/CallGraph.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/Method.h" #include "llvm/Method.h"
#include "llvm/Pass.h"
#include "Support/DepthFirstIterator.h" #include "Support/DepthFirstIterator.h"
#include <set> #include <set>
@ -45,18 +46,27 @@ static bool RemoveUnreachableMethods(Module *M, cfg::CallGraph &CallGraph) {
return true; return true;
} }
bool GlobalDCE::run(Module *M) { namespace {
return RemoveUnreachableMethods(M, getAnalysis<cfg::CallGraph>()); struct GlobalDCE : public Pass {
// run - Do the GlobalDCE pass on the specified module, optionally updating
// the specified callgraph to reflect the changes.
//
bool run(Module *M) {
return RemoveUnreachableMethods(M, getAnalysis<cfg::CallGraph>());
}
// getAnalysisUsageInfo - This function works on the call graph of a module.
// It is capable of updating the call graph to reflect the new state of the
// module.
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
Required.push_back(cfg::CallGraph::ID);
// FIXME: This should update the callgraph, not destroy it!
Destroyed.push_back(cfg::CallGraph::ID);
}
};
} }
// getAnalysisUsageInfo - This function works on the call graph of a module. Pass *createGlobalDCEPass() { return new GlobalDCE(); }
// It is capable of updating the call graph to reflect the new state of the
// module.
//
void GlobalDCE::getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
Required.push_back(cfg::CallGraph::ID);
// FIXME: This should update the callgraph, not destroy it!
Destroyed.push_back(cfg::CallGraph::ID);
}

View File

@ -21,6 +21,7 @@
#include "llvm/Transforms/MethodInlining.h" #include "llvm/Transforms/MethodInlining.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/Method.h" #include "llvm/Method.h"
#include "llvm/Pass.h"
#include "llvm/iTerminators.h" #include "llvm/iTerminators.h"
#include "llvm/iPHINode.h" #include "llvm/iPHINode.h"
#include "llvm/iOther.h" #include "llvm/iOther.h"
@ -249,7 +250,10 @@ static inline bool DoMethodInlining(BasicBlock *BB) {
return false; return false;
} }
bool MethodInlining::doMethodInlining(Method *M) { // doMethodInlining - Use a heuristic based approach to inline methods that
// seem to look good.
//
static bool doMethodInlining(Method *M) {
bool Changed = false; bool Changed = false;
// Loop through now and inline instructions a basic block at a time... // Loop through now and inline instructions a basic block at a time...
@ -264,3 +268,13 @@ bool MethodInlining::doMethodInlining(Method *M) {
return Changed; return Changed;
} }
namespace {
struct MethodInlining : public MethodPass {
virtual bool runOnMethod(Method *M) {
return doMethodInlining(M);
}
};
}
Pass *createMethodInliningPass() { return new MethodInlining(); }

View File

@ -19,6 +19,37 @@ using std::pair;
#include "llvm/Assembly/Writer.h" #include "llvm/Assembly/Writer.h"
namespace {
class SimpleStructMutation : public MutateStructTypes {
public:
enum Transform { SwapElements, SortElements } CurrentXForm;
SimpleStructMutation(enum Transform XForm) : CurrentXForm(XForm) {}
virtual bool run(Module *M) {
setTransforms(getTransforms(M, CurrentXForm));
bool Changed = MutateStructTypes::run(M);
clearTransforms();
return Changed;
}
// getAnalysisUsageInfo - This function needs the results of the
// FindUsedTypes and FindUnsafePointerTypes analysis passes...
//
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
Required.push_back(FindUsedTypes::ID);
Required.push_back(FindUnsafePointerTypes::ID);
MutateStructTypes::getAnalysisUsageInfo(Required, Destroyed, Provided);
}
private:
TransformsType getTransforms(Module *M, enum Transform);
};
} // end anonymous namespace
// PruneTypes - Given a type Ty, make sure that neither it, or one of its // PruneTypes - Given a type Ty, make sure that neither it, or one of its
// subtypes, occur in TypesToModify. // subtypes, occur in TypesToModify.
@ -87,6 +118,7 @@ static inline void GetTransformation(const StructType *ST,
} }
} }
SimpleStructMutation::TransformsType SimpleStructMutation::TransformsType
SimpleStructMutation::getTransforms(Module *M, enum Transform XForm) { SimpleStructMutation::getTransforms(Module *M, enum Transform XForm) {
// We need to know which types to modify, and which types we CAN'T modify // We need to know which types to modify, and which types we CAN'T modify
@ -137,13 +169,10 @@ SimpleStructMutation::TransformsType
} }
// getAnalysisUsageInfo - This function needs the results of the Pass *createSwapElementsPass() {
// FindUsedTypes and FindUnsafePointerTypes analysis passes... return new SimpleStructMutation(SimpleStructMutation::SwapElements);
//
void SimpleStructMutation::getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided){
Required.push_back(FindUsedTypes::ID);
Required.push_back(FindUnsafePointerTypes::ID);
MutateStructTypes::getAnalysisUsageInfo(Required, Destroyed, Provided);
} }
Pass *createSortElementsPass() {
return new SimpleStructMutation(SimpleStructMutation::SortElements);
}

View File

@ -15,12 +15,55 @@
#include "llvm/Method.h" #include "llvm/Method.h"
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/SymbolTable.h" #include "llvm/SymbolTable.h"
#include "llvm/Pass.h"
#include "llvm/Assembly/Writer.h" #include "llvm/Assembly/Writer.h"
#include "Support/StringExtras.h" #include "Support/StringExtras.h"
#include <sstream> #include <sstream>
using std::vector; using std::vector;
using std::string; using std::string;
namespace {
class InsertTraceCode : public MethodPass {
bool TraceBasicBlockExits, TraceMethodExits;
Method *PrintfMeth;
public:
InsertTraceCode(bool traceBasicBlockExits, bool traceMethodExits)
: TraceBasicBlockExits(traceBasicBlockExits),
TraceMethodExits(traceMethodExits) {}
// Add a prototype for printf if it is not already in the program.
//
bool doInitialization(Module *M);
//--------------------------------------------------------------------------
// Function InsertCodeToTraceValues
//
// Inserts tracing code for all live values at basic block and/or method
// exits as specified by `traceBasicBlockExits' and `traceMethodExits'.
//
static bool doit(Method *M, bool traceBasicBlockExits,
bool traceMethodExits, Method *Printf);
// runOnMethod - This method does the work. Always successful.
//
bool runOnMethod(Method *M) {
return doit(M, TraceBasicBlockExits, TraceMethodExits, PrintfMeth);
}
};
} // end anonymous namespace
Pass *createTraceValuesPassForMethod() { // Just trace methods
return new InsertTraceCode(false, true);
}
Pass *createTraceValuesPassForBasicBlocks() { // Trace BB's and methods
return new InsertTraceCode(true, true);
}
// Add a prototype for printf if it is not already in the program. // Add a prototype for printf if it is not already in the program.
// //
bool InsertTraceCode::doInitialization(Module *M) { bool InsertTraceCode::doInitialization(Module *M) {

View File

@ -12,6 +12,7 @@
#include "llvm/iOther.h" #include "llvm/iOther.h"
#include "llvm/iMemory.h" #include "llvm/iMemory.h"
#include "llvm/ConstantVals.h" #include "llvm/ConstantVals.h"
#include "llvm/Pass.h"
#include "llvm/Transforms/Scalar/DCE.h" #include "llvm/Transforms/Scalar/DCE.h"
#include "llvm/Transforms/Scalar/ConstantHandling.h" #include "llvm/Transforms/Scalar/ConstantHandling.h"
#include "llvm/Transforms/Scalar/ConstantProp.h" #include "llvm/Transforms/Scalar/ConstantProp.h"
@ -413,8 +414,7 @@ static bool DoRaisePass(Method *M) {
#if DEBUG_PEEPHOLE_INSTS #if DEBUG_PEEPHOLE_INSTS
cerr << "Processing: " << *BI; cerr << "Processing: " << *BI;
#endif #endif
if (DeadCodeElimination::dceInstruction(BIL, BI) || if (dceInstruction(BIL, BI) || doConstantPropogation(BB, BI)) {
ConstantPropogation::doConstantPropogation(BB, BI)) {
Changed = true; Changed = true;
#ifdef DEBUG_PEEPHOLE_INSTS #ifdef DEBUG_PEEPHOLE_INSTS
cerr << "DeadCode Elinated!\n"; cerr << "DeadCode Elinated!\n";
@ -429,12 +429,10 @@ static bool DoRaisePass(Method *M) {
} }
// RaisePointerReferences::doit - Raise a method representation to a higher // RaisePointerReferences::doit - Raise a method representation to a higher
// level. // level.
// //
bool RaisePointerReferences::doit(Method *M) { static bool doRPR(Method *M) {
#ifdef DEBUG_PEEPHOLE_INSTS #ifdef DEBUG_PEEPHOLE_INSTS
cerr << "\n\n\nStarting to work on Method '" << M->getName() << "'\n"; cerr << "\n\n\nStarting to work on Method '" << M->getName() << "'\n";
#endif #endif
@ -459,3 +457,15 @@ bool RaisePointerReferences::doit(Method *M) {
return Changed; return Changed;
} }
namespace {
struct RaisePointerReferences : public MethodPass {
virtual bool runOnMethod(Method *M) { return doRPR(M); }
};
}
Pass *createRaisePointerReferencesPass() {
return new RaisePointerReferences();
}

View File

@ -288,21 +288,24 @@ BasicBlock *ADCE::fixupCFG(BasicBlock *BB, std::set<BasicBlock*> &VisitedBlocks,
} }
} }
namespace {
struct AgressiveDCE : public MethodPass {
// doADCE - Execute the Agressive Dead Code Elimination Algorithm // doADCE - Execute the Agressive Dead Code Elimination Algorithm
// //
bool AgressiveDCE::runOnMethod(Method *M) { virtual bool runOnMethod(Method *M) {
return ADCE(M).doADCE( return ADCE(M).doADCE(
getAnalysis<cfg::DominanceFrontier>(cfg::DominanceFrontier::PostDomID)); getAnalysis<cfg::DominanceFrontier>(cfg::DominanceFrontier::PostDomID));
}
// getAnalysisUsageInfo - We require post dominance frontiers (aka Control
// Dependence Graph)
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
Requires.push_back(cfg::DominanceFrontier::PostDomID);
}
};
} }
Pass *createAgressiveDCEPass() {
// getAnalysisUsageInfo - We require post dominance frontiers (aka Control return new AgressiveDCE();
// Dependence Graph)
//
void AgressiveDCE::getAnalysisUsageInfo(Pass::AnalysisSet &Requires,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
Requires.push_back(cfg::DominanceFrontier::PostDomID);
} }

View File

@ -29,6 +29,7 @@
#include "llvm/iTerminators.h" #include "llvm/iTerminators.h"
#include "llvm/iPHINode.h" #include "llvm/iPHINode.h"
#include "llvm/iOther.h" #include "llvm/iOther.h"
#include "llvm/Pass.h"
#include "llvm/ConstantVals.h" #include "llvm/ConstantVals.h"
inline static bool inline static bool
@ -153,8 +154,7 @@ bool ConstantFoldTerminator(TerminatorInst *T) {
// ConstantFoldInstruction - If an instruction references constants, try to fold // ConstantFoldInstruction - If an instruction references constants, try to fold
// them together... // them together...
// //
bool ConstantPropogation::doConstantPropogation(BasicBlock *BB, bool doConstantPropogation(BasicBlock *BB, BasicBlock::iterator &II) {
BasicBlock::iterator &II) {
Instruction *Inst = *II; Instruction *Inst = *II;
if (isa<BinaryOperator>(Inst)) { if (isa<BinaryOperator>(Inst)) {
Constant *D1 = dyn_cast<Constant>(Inst->getOperand(0)); Constant *D1 = dyn_cast<Constant>(Inst->getOperand(0));
@ -200,7 +200,7 @@ static bool DoConstPropPass(Method *M) {
for (Method::iterator BBI = M->begin(); BBI != M->end(); ++BBI) { for (Method::iterator BBI = M->begin(); BBI != M->end(); ++BBI) {
BasicBlock *BB = *BBI; BasicBlock *BB = *BBI;
for (BasicBlock::iterator I = BB->begin(); I != BB->end(); ) for (BasicBlock::iterator I = BB->begin(); I != BB->end(); )
if (ConstantPropogation::doConstantPropogation(BB, I)) if (doConstantPropogation(BB, I))
SomethingChanged = true; SomethingChanged = true;
else else
++I; ++I;
@ -208,14 +208,20 @@ static bool DoConstPropPass(Method *M) {
return SomethingChanged; return SomethingChanged;
} }
namespace {
struct ConstantPropogation : public MethodPass {
inline bool runOnMethod(Method *M) {
bool Modified = false;
// returns whether or not the underlying method was modified // Fold constants until we make no progress...
// while (DoConstPropPass(M)) Modified = true;
bool ConstantPropogation::doConstantPropogation(Method *M) {
bool Modified = false; return Modified;
}
// Fold constants until we make no progress... };
while (DoConstPropPass(M)) Modified = true;
return Modified;
} }
Pass *createConstantPropogationPass() {
return new ConstantPropogation();
}

View File

@ -32,6 +32,7 @@
#include "llvm/iPHINode.h" #include "llvm/iPHINode.h"
#include "llvm/Assembly/Writer.h" #include "llvm/Assembly/Writer.h"
#include "llvm/Support/CFG.h" #include "llvm/Support/CFG.h"
#include "llvm/Pass.h"
#include "Support/STLExtras.h" #include "Support/STLExtras.h"
#include <algorithm> #include <algorithm>
@ -40,8 +41,8 @@
// to point to the instruction that immediately succeeded the original // to point to the instruction that immediately succeeded the original
// instruction. // instruction.
// //
bool DeadCodeElimination::dceInstruction(BasicBlock::InstListType &BBIL, bool dceInstruction(BasicBlock::InstListType &BBIL,
BasicBlock::iterator &BBI) { BasicBlock::iterator &BBI) {
// Look for un"used" definitions... // Look for un"used" definitions...
if ((*BBI)->use_empty() && !(*BBI)->hasSideEffects() && if ((*BBI)->use_empty() && !(*BBI)->hasSideEffects() &&
!isa<TerminatorInst>(*BBI)) { !isa<TerminatorInst>(*BBI)) {
@ -55,15 +56,21 @@ static inline bool RemoveUnusedDefs(BasicBlock::InstListType &Vals) {
bool Changed = false; bool Changed = false;
for (BasicBlock::InstListType::iterator DI = Vals.begin(); for (BasicBlock::InstListType::iterator DI = Vals.begin();
DI != Vals.end(); ) DI != Vals.end(); )
if (DeadCodeElimination::dceInstruction(Vals, DI)) if (dceInstruction(Vals, DI))
Changed = true; Changed = true;
else else
++DI; ++DI;
return Changed; return Changed;
} }
bool DeadInstElimination::runOnBasicBlock(BasicBlock *BB) { struct DeadInstElimination : public BasicBlockPass {
return RemoveUnusedDefs(BB->getInstList()); virtual bool runOnBasicBlock(BasicBlock *BB) {
return RemoveUnusedDefs(BB->getInstList());
}
};
Pass *createDeadInstEliminationPass() {
return new DeadInstElimination();
} }
// RemoveSingularPHIs - This removes PHI nodes from basic blocks that have only // RemoveSingularPHIs - This removes PHI nodes from basic blocks that have only
@ -297,17 +304,11 @@ static bool DoDCEPass(Method *M) {
return Changed; return Changed;
} }
// Remove unused global values - This removes unused global values of no
// It is possible that we may require multiple passes over the code to fully // possible value. This currently includes unused method prototypes and
// eliminate dead code. Iterate until we are done. // unitialized global variables.
// //
bool DeadCodeElimination::doDCE(Method *M) { static bool RemoveUnusedGlobalValues(Module *Mod) {
bool Changed = false;
while (DoDCEPass(M)) Changed = true;
return Changed;
}
bool DeadCodeElimination::RemoveUnusedGlobalValues(Module *Mod) {
bool Changed = false; bool Changed = false;
for (Module::iterator MI = Mod->begin(); MI != Mod->end(); ) { for (Module::iterator MI = Mod->begin(); MI != Mod->end(); ) {
@ -338,3 +339,30 @@ bool DeadCodeElimination::RemoveUnusedGlobalValues(Module *Mod) {
return Changed; return Changed;
} }
namespace {
struct DeadCodeElimination : public MethodPass {
// Pass Interface...
virtual bool doInitialization(Module *M) {
return RemoveUnusedGlobalValues(M);
}
// It is possible that we may require multiple passes over the code to fully
// eliminate dead code. Iterate until we are done.
//
virtual bool runOnMethod(Method *M) {
bool Changed = false;
while (DoDCEPass(M)) Changed = true;
return Changed;
}
virtual bool doFinalization(Module *M) {
return RemoveUnusedGlobalValues(M);
}
};
}
Pass *createDeadCodeEliminationPass() {
return new DeadCodeElimination();
}

View File

@ -13,6 +13,7 @@
#include "llvm/Type.h" #include "llvm/Type.h"
#include "llvm/BasicBlock.h" #include "llvm/BasicBlock.h"
#include "llvm/ConstantVals.h" #include "llvm/ConstantVals.h"
#include "llvm/Pass.h"
#include "llvm/Support/CFG.h" #include "llvm/Support/CFG.h"
#include "Support/STLExtras.h" #include "Support/STLExtras.h"
@ -186,19 +187,29 @@ static bool TransformLoop(cfg::LoopInfo *Loops, cfg::Loop *Loop) {
return Changed; return Changed;
} }
bool InductionVariableSimplify::doit(Method *M, cfg::LoopInfo &Loops) { static bool doit(Method *M, cfg::LoopInfo &Loops) {
// Induction Variables live in the header nodes of the loops of the method... // Induction Variables live in the header nodes of the loops of the method...
return reduce_apply_bool(Loops.getTopLevelLoops().begin(), return reduce_apply_bool(Loops.getTopLevelLoops().begin(),
Loops.getTopLevelLoops().end(), Loops.getTopLevelLoops().end(),
std::bind1st(std::ptr_fun(TransformLoop), &Loops)); std::bind1st(std::ptr_fun(TransformLoop), &Loops));
} }
bool InductionVariableSimplify::runOnMethod(Method *M) {
return doit(M, getAnalysis<cfg::LoopInfo>()); namespace {
struct InductionVariableSimplify : public MethodPass {
virtual bool runOnMethod(Method *M) {
return doit(M, getAnalysis<cfg::LoopInfo>());
}
virtual void getAnalysisUsageInfo(Pass::AnalysisSet &Required,
Pass::AnalysisSet &Destroyed,
Pass::AnalysisSet &Provided) {
Required.push_back(cfg::LoopInfo::ID);
}
};
} }
void InductionVariableSimplify::getAnalysisUsageInfo(Pass::AnalysisSet &Req, Pass *createIndVarSimplifyPass() {
Pass::AnalysisSet &Dest, return new InductionVariableSimplify();
Pass::AnalysisSet &Prov) {
Req.push_back(cfg::LoopInfo::ID);
} }

View File

@ -19,6 +19,7 @@
#include "llvm/Method.h" #include "llvm/Method.h"
#include "llvm/iMemory.h" #include "llvm/iMemory.h"
#include "llvm/InstrTypes.h" #include "llvm/InstrTypes.h"
#include "llvm/Pass.h"
#include "llvm/Support/InstIterator.h" #include "llvm/Support/InstIterator.h"
#include "../TransformInternals.h" #include "../TransformInternals.h"
@ -37,7 +38,15 @@ static Instruction *CombineBinOp(BinaryOperator *I) {
LocalChange = false; LocalChange = false;
Value *Op1 = I->getOperand(0); Value *Op1 = I->getOperand(0);
if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(1))) { if (Constant *Op2 = dyn_cast<Constant>(I->getOperand(1))) {
if (I->getOpcode() == Instruction::Add) { switch (I->getOpcode()) {
case Instruction::Add:
if (I->getType()->isIntegral() && cast<ConstantInt>(Op2)->equalsInt(0)){
// Eliminate 'add int %X, 0'
I->replaceAllUsesWith(Op1); // FIXME: This breaks the worklist
LocalChange = true;
break;
}
if (Instruction *IOp1 = dyn_cast<Instruction>(Op1)) { if (Instruction *IOp1 = dyn_cast<Instruction>(Op1)) {
if (IOp1->getOpcode() == Instruction::Add && if (IOp1->getOpcode() == Instruction::Add &&
isa<Constant>(IOp1->getOperand(1))) { isa<Constant>(IOp1->getOperand(1))) {
@ -54,10 +63,23 @@ static Instruction *CombineBinOp(BinaryOperator *I) {
I->setOperand(0, IOp1->getOperand(0)); I->setOperand(0, IOp1->getOperand(0));
I->setOperand(1, Val); I->setOperand(1, Val);
LocalChange = true; LocalChange = true;
break;
} }
} }
} }
break;
case Instruction::Mul:
if (I->getType()->isIntegral() && cast<ConstantInt>(Op2)->equalsInt(1)){
// Eliminate 'mul int %X, 1'
I->replaceAllUsesWith(Op1); // FIXME: This breaks the worklist
LocalChange = true;
break;
}
default:
break;
} }
} }
Changed |= LocalChange; Changed |= LocalChange;
@ -110,7 +132,7 @@ static Instruction *CombineIndicies(MemAccessInst *MAI) {
return 0; return 0;
} }
bool InstructionCombining::CombineInstruction(Instruction *I) { static bool CombineInstruction(Instruction *I) {
Instruction *Result = 0; Instruction *Result = 0;
if (BinaryOperator *BOP = dyn_cast<BinaryOperator>(I)) if (BinaryOperator *BOP = dyn_cast<BinaryOperator>(I))
Result = CombineBinOp(BOP); Result = CombineBinOp(BOP);
@ -125,8 +147,7 @@ bool InstructionCombining::CombineInstruction(Instruction *I) {
return true; return true;
} }
static bool doInstCombining(Method *M) {
bool InstructionCombining::doit(Method *M) {
// Start the worklist out with all of the instructions in the method in it. // Start the worklist out with all of the instructions in the method in it.
std::vector<Instruction*> WorkList(inst_begin(M), inst_end(M)); std::vector<Instruction*> WorkList(inst_begin(M), inst_end(M));
@ -148,3 +169,13 @@ bool InstructionCombining::doit(Method *M) {
return false; return false;
} }
namespace {
struct InstructionCombining : public MethodPass {
virtual bool runOnMethod(Method *M) { return doInstCombining(M); }
};
}
Pass *createInstructionCombiningPass() {
return new InstructionCombining();
}

View File

@ -25,6 +25,7 @@
#include "llvm/iMemory.h" #include "llvm/iMemory.h"
#include "llvm/iTerminators.h" #include "llvm/iTerminators.h"
#include "llvm/iOther.h" #include "llvm/iOther.h"
#include "llvm/Pass.h"
#include "llvm/Assembly/Writer.h" #include "llvm/Assembly/Writer.h"
#include "Support/STLExtras.h" #include "Support/STLExtras.h"
#include <algorithm> #include <algorithm>
@ -503,11 +504,18 @@ void SCCP::OperandChangedState(User *U) {
UpdateInstruction(I); UpdateInstruction(I);
} }
namespace {
// DoSparseConditionalConstantProp - Use Sparse Conditional Constant Propogation // SCCPPass - Use Sparse Conditional Constant Propogation
// to prove whether a value is constant and whether blocks are used. // to prove whether a value is constant and whether blocks are used.
// //
bool SCCPPass::doSCCP(Method *M) { struct SCCPPass : public MethodPass {
SCCP S(M); inline bool runOnMethod(Method *M) {
return S.doSCCP(); SCCP S(M);
return S.doSCCP();
}
};
}
Pass *createSCCPPass() {
return new SCCPPass();
} }

View File

@ -18,6 +18,7 @@
#include "llvm/Module.h" #include "llvm/Module.h"
#include "llvm/Method.h" #include "llvm/Method.h"
#include "llvm/SymbolTable.h" #include "llvm/SymbolTable.h"
#include "llvm/Pass.h"
static bool StripSymbolTable(SymbolTable *SymTab) { static bool StripSymbolTable(SymbolTable *SymTab) {
if (SymTab == 0) return false; // No symbol table? No problem. if (SymTab == 0) return false; // No symbol table? No problem.
@ -44,16 +45,38 @@ static bool StripSymbolTable(SymbolTable *SymTab) {
// DoSymbolStripping - Remove all symbolic information from a method // DoSymbolStripping - Remove all symbolic information from a method
// //
bool SymbolStripping::doSymbolStripping(Method *M) { static bool doSymbolStripping(Method *M) {
return StripSymbolTable(M->getSymbolTable()); return StripSymbolTable(M->getSymbolTable());
} }
// doStripGlobalSymbols - Remove all symbolic information from all methods // doStripGlobalSymbols - Remove all symbolic information from all methods
// in a module, and all module level symbols. (method names, etc...) // in a module, and all module level symbols. (method names, etc...)
// //
bool FullSymbolStripping::doStripGlobalSymbols(Module *M) { static bool doStripGlobalSymbols(Module *M) {
// Remove all symbols from methods in this module... and then strip all of the // Remove all symbols from methods in this module... and then strip all of the
// symbols in this module... // symbols in this module...
// //
return StripSymbolTable(M->getSymbolTable()); return StripSymbolTable(M->getSymbolTable());
} }
namespace {
struct SymbolStripping : public MethodPass {
virtual bool runOnMethod(Method *M) {
return doSymbolStripping(M);
}
};
struct FullSymbolStripping : public SymbolStripping {
virtual bool doInitialization(Module *M) {
return doStripGlobalSymbols(M);
}
};
}
Pass *createSymbolStrippingPass() {
return new SymbolStripping();
}
Pass *createFullSymbolStrippingPass() {
return new FullSymbolStripping();
}

View File

@ -15,9 +15,57 @@
#include "llvm/iOther.h" #include "llvm/iOther.h"
#include "llvm/SymbolTable.h" #include "llvm/SymbolTable.h"
#include "llvm/ConstantVals.h" #include "llvm/ConstantVals.h"
#include "llvm/Pass.h"
#include "TransformInternals.h" #include "TransformInternals.h"
using std::vector; using std::vector;
namespace {
// LowerAllocations - Turn malloc and free instructions into %malloc and %free
// calls.
//
class LowerAllocations : public BasicBlockPass {
Method *MallocMeth; // Methods in the module we are processing
Method *FreeMeth; // Initialized by doInitialization
const TargetData &DataLayout;
public:
inline LowerAllocations(const TargetData &TD) : DataLayout(TD) {
MallocMeth = FreeMeth = 0;
}
// doPassInitialization - For the lower allocations pass, this ensures that a
// module contains a declaration for a malloc and a free function.
//
bool doInitialization(Module *M);
// runOnBasicBlock - This method does the actual work of converting
// instructions over, assuming that the pass has already been initialized.
//
bool runOnBasicBlock(BasicBlock *BB);
};
// RaiseAllocations - Turn %malloc and %free calls into the appropriate
// instruction.
//
class RaiseAllocations : public BasicBlockPass {
Method *MallocMeth; // Methods in the module we are processing
Method *FreeMeth; // Initialized by doPassInitializationVirt
public:
inline RaiseAllocations() : MallocMeth(0), FreeMeth(0) {}
// doPassInitialization - For the raise allocations pass, this finds a
// declaration for malloc and free if they exist.
//
bool doInitialization(Module *M);
// runOnBasicBlock - This method does the actual work of converting
// instructions over, assuming that the pass has already been initialized.
//
bool runOnBasicBlock(BasicBlock *BB);
};
} // end anonymous namespace
// doInitialization - For the lower allocations pass, this ensures that a // doInitialization - For the lower allocations pass, this ensures that a
// module contains a declaration for a malloc and a free function. // module contains a declaration for a malloc and a free function.
@ -181,3 +229,12 @@ bool RaiseAllocations::runOnBasicBlock(BasicBlock *BB) {
return Changed; return Changed;
} }
Pass *createLowerAllocationsPass(const TargetData &TD) {
return new LowerAllocations(TD);
}
Pass *createRaiseAllocationsPass() {
return new RaiseAllocations();
}

View File

@ -53,27 +53,7 @@ enum Opts {
globaldce, swapstructs, sortstructs, globaldce, swapstructs, sortstructs,
}; };
static Pass *createPrintMethodPass() {
// New template functions - Provide functions that return passes of specified
// types, with specified arguments...
//
template<class PassClass>
Pass *New() {
return new PassClass();
}
template<class PassClass, typename ArgTy1, ArgTy1 Arg1>
Pass *New() {
return new PassClass(Arg1);
}
template<class PassClass, typename ArgTy1, ArgTy1 Arg1,
typename ArgTy2, ArgTy1 Arg2>
Pass *New() {
return new PassClass(Arg1, Arg2);
}
static Pass *NewPrintMethodPass() {
return new PrintMethodPass("Current Method: \n", &cerr); return new PrintMethodPass("Current Method: \n", &cerr);
} }
@ -83,35 +63,33 @@ struct {
enum Opts OptID; enum Opts OptID;
Pass * (*PassCtor)(); Pass * (*PassCtor)();
} OptTable[] = { } OptTable[] = {
{ dce , New<DeadCodeElimination> }, { dce , createDeadCodeEliminationPass },
{ constprop , New<ConstantPropogation> }, { constprop , createConstantPropogationPass },
{ inlining , New<MethodInlining> }, { inlining , createMethodInliningPass },
{ constmerge , New<ConstantMerge> }, { constmerge , createConstantMergePass },
{ strip , New<SymbolStripping> }, { strip , createSymbolStrippingPass },
{ mstrip , New<FullSymbolStripping> }, { mstrip , createFullSymbolStrippingPass },
{ mergereturn, New<UnifyMethodExitNodes> }, { mergereturn, createUnifyMethodExitNodesPass },
{ indvars , New<InductionVariableSimplify> }, { indvars , createIndVarSimplifyPass },
{ instcombine, New<InstructionCombining> }, { instcombine, createInstructionCombiningPass },
{ sccp , New<SCCPPass> }, { sccp , createSCCPPass },
{ adce , New<AgressiveDCE> }, { adce , createAgressiveDCEPass },
{ raise , New<RaisePointerReferences> }, { raise , createRaisePointerReferencesPass },
{ mem2reg , newPromoteMemoryToRegister }, { mem2reg , newPromoteMemoryToRegister },
{ trace , New<InsertTraceCode, bool, true, bool, true> }, { trace , createTraceValuesPassForBasicBlocks },
{ tracem , New<InsertTraceCode, bool, false, bool, true> }, { tracem , createTraceValuesPassForMethod },
{ paths , createProfilePathsPass }, { paths , createProfilePathsPass },
{ print , NewPrintMethodPass }, { print , createPrintMethodPass },
{ verify , createVerifierPass }, { verify , createVerifierPass },
{ raiseallocs, New<RaiseAllocations> }, { raiseallocs, createRaiseAllocationsPass },
{ cleangcc , New<CleanupGCCOutput> }, { cleangcc , createCleanupGCCOutputPass },
{ globaldce , New<GlobalDCE> }, { globaldce , createGlobalDCEPass },
{ swapstructs, New<SimpleStructMutation, SimpleStructMutation::Transform, { swapstructs, createSwapElementsPass },
SimpleStructMutation::SwapElements>}, { sortstructs, createSortElementsPass },
{ sortstructs, New<SimpleStructMutation, SimpleStructMutation::Transform,
SimpleStructMutation::SortElements>},
}; };
// Command line option handling code... // Command line option handling code...