[llvm-commits] CVS: llvm-poolalloc/lib/Macroscopic/DeadFieldElimination.cpp StructureFieldVisitor.h
Chris Lattner
lattner at cs.uiuc.edu
Sat May 7 09:13:29 PDT 2005
Changes in directory llvm-poolalloc/lib/Macroscopic:
DeadFieldElimination.cpp added (r1.1)
StructureFieldVisitor.h updated: 1.3 -> 1.4
---
Log message:
a new test driver
---
Diffs of the changes: (+248 -1)
DeadFieldElimination.cpp | 248 +++++++++++++++++++++++++++++++++++++++++++++++
StructureFieldVisitor.h | 1
2 files changed, 248 insertions(+), 1 deletion(-)
Index: llvm-poolalloc/lib/Macroscopic/DeadFieldElimination.cpp
diff -c /dev/null llvm-poolalloc/lib/Macroscopic/DeadFieldElimination.cpp:1.1
*** /dev/null Sat May 7 11:13:22 2005
--- llvm-poolalloc/lib/Macroscopic/DeadFieldElimination.cpp Sat May 7 11:13:12 2005
***************
*** 0 ****
--- 1,248 ----
+ //===-- DeadFieldElimination.cpp - Dead Field Elimination 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 file implements the -rds-deadfieldelim pass, which implements
+ // Macroscopic Dead Field Elimination.
+ //
+ //===----------------------------------------------------------------------===//
+
+ #define DEBUG_TYPE "rds-deadfieldelim"
+ #include "StructureFieldVisitor.h"
+ #include "llvm/Analysis/DataStructure/DataStructure.h"
+ #include "llvm/Analysis/DataStructure/DSGraph.h"
+ #include "llvm/Support/Debug.h"
+ #include "llvm/Support/Timer.h"
+ using namespace llvm;
+ using namespace llvm::Macroscopic;
+
+ namespace {
+ /// DeadFieldElim - This class implements the dead field elimination
+ /// optimization. This transformation is a very simple macroscopic
+ /// optimization whose high-level algorithm works like this:
+ ///
+ /// 1. Identify all type-homogenous data structures that only contain HGS
+ /// composition bits.
+ /// 2. For each data structure, visit every load of fields in the node.
+ /// Keep track of whether a field is ever loaded.
+ /// 3. If we found fields that are never loaded from, rewrite the affected
+ /// data structures, deleting the dead fields!
+ ///
+ class DeadFieldElim : public ModulePass {
+
+ bool runOnModule(Module &M);
+
+ void getAnalysisUsage(AnalysisUsage &AU) const {
+ // Need information from DSA.
+ AU.addRequired<EquivClassGraphs>();
+ AU.addPreserved<EquivClassGraphs>();
+ }
+ };
+ RegisterOpt<DeadFieldElim>
+ X("rds-deadfieldelim", "Macroscopic Dead Field Elimination");
+ } // end anonymous namespace
+
+
+ namespace {
+ /// DeadFieldElimLattice - This is the most trivial lattice possible: it
+ /// consists of two states, dead (the default) and alive (overdefined,
+ /// bottom). Because it has only two states, it does not need to maintain any
+ /// actual state.
+ struct DeadFieldElimLattice : public LatticeValue {
+ DeadFieldElimLattice(DSNode *Node, const std::vector<unsigned> &Idxs,
+ const Type *FieldTy)
+ : LatticeValue(Node, Idxs, FieldTy) {}
+
+ // getInterestingEvents - We only care about reads from memory?
+ static unsigned getInterestingEvents() { return Macroscopic::Visit::Loads; }
+
+ virtual void dump() const {
+ LatticeValue::dump();
+ std::cerr << " DEAD FIELD!\n";
+ }
+
+ // create - Return a dataflow fact for this field, initialized to top.
+ static DeadFieldElimLattice *create(DSNode *Node,
+ const std::vector<unsigned> &Idxs,
+ const Type *FieldTy) {
+ return new DeadFieldElimLattice(Node, Idxs, FieldTy);
+ }
+
+ virtual bool mergeInValue(const LatticeValue *RHS) {
+ return false; // Neither LHS nor RHS are overdefined.
+ }
+
+ // VisitLoad - Load events always move us to bottom.
+ virtual bool visitLoad(LoadInst &LI) {
+ return true; // Bottom!
+ }
+ };
+ }
+
+
+ #include "llvm/Constants.h"
+ #include "llvm/Instructions.h"
+ namespace {
+ /// ConstPropLattice - This is the standard 3-level constant propagation
+ /// lattice. When CstVal is null it is undefined, when it is non-null it is
+ /// defined to that constant, and it hits bottom of set to something
+ /// unanalyzable or multiple values.
+ struct ConstPropLattice : public LatticeValue {
+ Constant *CstVal;
+
+ ConstPropLattice(DSNode *Node, const std::vector<unsigned> &Idxs,
+ const Type *FieldTy)
+ : LatticeValue(Node, Idxs, FieldTy), CstVal(0) {}
+
+ // getInterestingEvents - We only care about reads from memory?
+ static unsigned getInterestingEvents() { return Macroscopic::Visit::Stores;}
+
+ // create - Return a dataflow fact for this field, initialized to top.
+ static ConstPropLattice *create(DSNode *Node,
+ const std::vector<unsigned> &Idxs,
+ const Type *FieldTy) {
+ return new ConstPropLattice(Node, Idxs, FieldTy);
+ }
+
+ bool mergeInValue(Constant *V) {
+ if (V == 0 || isa<UndefValue>(V)) return false;
+ if (CstVal == 0)
+ CstVal = V;
+ else if (CstVal != V)
+ return true;
+ return false;
+ }
+
+ virtual void dump() const {
+ LatticeValue::dump();
+ if (CstVal)
+ std::cerr << " CONSTANT VALUE = " << *CstVal << "\n";
+ else
+ std::cerr << " FIELD NEVER DEFINED!\n";
+ }
+
+ virtual bool mergeInValue(const LatticeValue *RHSLV) {
+ const ConstPropLattice *RHS = static_cast<const ConstPropLattice*>(RHSLV);
+ return mergeInValue(RHS->CstVal);
+ }
+
+ virtual bool visitStore(StoreInst &SI) {
+ if (Constant *CV = dyn_cast<Constant>(SI.getOperand(0)))
+ return mergeInValue(CV);
+ return true; // Bottom!
+ }
+
+ bool visitGlobalInit(Constant *InitVal) {
+ return mergeInValue(InitVal);
+ }
+
+ virtual bool visitMemSet(CallInst &I) {
+ if (Constant *C = dyn_cast<Constant>(I.getOperand(2)))
+ if (C->isNullValue()) {
+ std::cerr << "HANDLED MEMSET: " << I;
+ return mergeInValue(Constant::getNullValue(getFieldType()));
+ }
+ return true;
+ }
+ };
+ }
+
+
+
+ bool DeadFieldElim::runOnModule(Module &M) {
+ EquivClassGraphs &ECG = getAnalysis<EquivClassGraphs>();
+
+ // Step #1: Identify all type-homogenous HGS (non-U) data structure nodes.
+ std::set<DSNode*> Nodes;
+
+ { NamedRegionTimer XX("Dead Fields");
+
+ FindAllDataStructures(Nodes, 0 /*nothing required*/,
+ DSNode::UnknownNode, true /*typesafe*/, ECG);
+
+ DEBUG(std::cerr << "DeadFieldElim: Found " << Nodes.size()
+ << " eligible data structure nodes.\n");
+
+ // Step #2: For each data structure, visit every load of fields in the node.
+ // Keep track of whether a field is ever loaded. The visitor returns a set of
+ // lattice values that have not reached bottom (in this case, that means it
+ // returns a set of dead fields).
+ std::set<DeadFieldElimLattice*> DeadFields =
+ StructureFieldVisitor<DeadFieldElimLattice>(ECG).visit(Nodes);
+
+ DEBUG(std::cerr << "DeadFieldElim: Found " << DeadFields.size()
+ << " dead fields!\n");
+ for (std::set<DeadFieldElimLattice*>::iterator I = DeadFields.begin(),
+ E = DeadFields.end(); I != E; ++I) {
+ DEBUG((*I)->dump());
+ delete *I;
+ }
+ DEBUG(std::cerr << "\n");
+ }
+ //return true;
+
+ { NamedRegionTimer XX("Constants");
+
+ Nodes.clear();
+ FindAllDataStructures(Nodes, 0 /*nothing required*/,
+ DSNode::UnknownNode, true /*typesafe*/, ECG);
+
+ // Step #2: For each data structure, visit every stores to fields in the node.
+ // Keep track of whether a field is always constant. The visitor returns a
+ // set of lattice values that have not reached bottom (in this case, that
+ // means they are either undefined or overdefined.
+ std::set<ConstPropLattice*> ConstantFields =
+ StructureFieldVisitor<ConstPropLattice>(ECG).visit(Nodes);
+
+ DEBUG(std::cerr << "ConstProp: Found " << ConstantFields.size()
+ << " constant or uninitialized fields!\n");
+ for (std::set<ConstPropLattice*>::iterator I = ConstantFields.begin(),
+ E = ConstantFields.end(); I != E; ++I) {
+ DEBUG((*I)->dump());
+ delete *I;
+ }
+ DEBUG(std::cerr << "\n");
+
+ }
+
+ return true;
+
+ // NOTE: We could do a simple thing that checks for fields whose loads are
+ // immediately casted to something smaller, and stores that are casted from
+ // something smaller to shrink them.
+
+
+ { NamedRegionTimer XX("Combined");
+
+ Nodes.clear();
+ FindAllDataStructures(Nodes, 0 /*nothing required*/,
+ DSNode::UnknownNode, true /*typesafe*/, ECG);
+
+ typedef CombinedLatticeValue<DeadFieldElimLattice,ConstPropLattice>
+ CombinedLattice;
+
+ // Step #2: For each data structure, visit every stores to fields in the node.
+ // Keep track of whether a field is always constant. The visitor returns a
+ // set of lattice values that have not reached bottom (in this case, that
+ // means they are either undefined or overdefined.
+ std::set<CombinedLattice*> CombinedFields =
+ StructureFieldVisitor<CombinedLattice>(ECG).visit(Nodes);
+
+ DEBUG(std::cerr << "Combined: Found " << CombinedFields.size()
+ << " interesting fields!\n");
+ for (std::set<CombinedLattice*>::iterator I = CombinedFields.begin(),
+ E = CombinedFields.end(); I != E; ++I) {
+ DEBUG((*I)->dump());
+ delete *I;
+ }
+ DEBUG(std::cerr << "\n");
+
+ }
+
+ return true;
+ }
Index: llvm-poolalloc/lib/Macroscopic/StructureFieldVisitor.h
diff -u llvm-poolalloc/lib/Macroscopic/StructureFieldVisitor.h:1.3 llvm-poolalloc/lib/Macroscopic/StructureFieldVisitor.h:1.4
--- llvm-poolalloc/lib/Macroscopic/StructureFieldVisitor.h:1.3 Sun Apr 24 15:09:19 2005
+++ llvm-poolalloc/lib/Macroscopic/StructureFieldVisitor.h Sat May 7 11:13:12 2005
@@ -56,7 +56,6 @@
//===----------------------------------------------------------------------===//
/// LatticeValue - Describe.
///
-
class LatticeValue {
DSNode *Node;
std::vector<unsigned> Idxs; // The index path to get to this field.
More information about the llvm-commits
mailing list