diff options
author | Chris Lattner <sabre@nondot.org> | 2004-01-09 18:15:24 +0000 |
---|---|---|
committer | Chris Lattner <sabre@nondot.org> | 2004-01-09 18:15:24 +0000 |
commit | 4ee36320f4b5b9724714f8be18d73cca71793794 (patch) | |
tree | 34cd3cb38e845ad75e58abd64497fe01ba2745ea /llvm/lib/Target/Sparc | |
parent | bb6fa4b32742f4587e6abbfd784acab41a42005e (diff) | |
download | bcm5719-llvm-4ee36320f4b5b9724714f8be18d73cca71793794.tar.gz bcm5719-llvm-4ee36320f4b5b9724714f8be18d73cca71793794.zip |
Move sparc-specific livevar code into lib/Target/Sparc
llvm-svn: 10733
Diffstat (limited to 'llvm/lib/Target/Sparc')
-rw-r--r-- | llvm/lib/Target/Sparc/LiveVar/BBLiveVar.cpp | 230 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/LiveVar/BBLiveVar.h | 90 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/LiveVar/FunctionLiveVarInfo.cpp | 322 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/LiveVar/Makefile | 14 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/LiveVar/ValueSet.cpp | 31 | ||||
-rw-r--r-- | llvm/lib/Target/Sparc/Makefile | 2 |
6 files changed, 688 insertions, 1 deletions
diff --git a/llvm/lib/Target/Sparc/LiveVar/BBLiveVar.cpp b/llvm/lib/Target/Sparc/LiveVar/BBLiveVar.cpp new file mode 100644 index 00000000000..f54b42ab12a --- /dev/null +++ b/llvm/lib/Target/Sparc/LiveVar/BBLiveVar.cpp @@ -0,0 +1,230 @@ +//===-- BBLiveVar.cpp - Live Variable Analysis for a BasicBlock -----------===// +// +// 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 is a wrapper class for BasicBlock which is used by live var analysis. +// +//===----------------------------------------------------------------------===// + +#include "BBLiveVar.h" +#include "llvm/CodeGen/FunctionLiveVarInfo.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineBasicBlock.h" +#include "llvm/Support/CFG.h" +#include "Support/SetOperations.h" +#include "../SparcInternals.h" + +namespace llvm { + +BBLiveVar::BBLiveVar(const BasicBlock &bb, MachineBasicBlock &mbb, unsigned id) + : BB(bb), MBB(mbb), POID(id) { + InSetChanged = OutSetChanged = false; + + calcDefUseSets(); +} + +//----------------------------------------------------------------------------- +// calculates def and use sets for each BB +// There are two passes over operands of a machine instruction. This is +// because, we can have instructions like V = V + 1, since we no longer +// assume single definition. +//----------------------------------------------------------------------------- + +void BBLiveVar::calcDefUseSets() { + // iterate over all the machine instructions in BB + for (MachineBasicBlock::const_reverse_iterator MII = MBB.rbegin(), + MIE = MBB.rend(); MII != MIE; ++MII) { + const MachineInstr *MI = *MII; + + if (DEBUG_LV >= LV_DEBUG_Verbose) { + std::cerr << " *Iterating over machine instr "; + MI->dump(); + std::cerr << "\n"; + } + + // iterate over MI operands to find defs + for (MachineInstr::const_val_op_iterator OpI = MI->begin(), OpE = MI->end(); + OpI != OpE; ++OpI) + if (OpI.isDef()) // add to Defs if this operand is a def + addDef(*OpI); + + // do for implicit operands as well + for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i) + if (MI->getImplicitOp(i).isDef()) + addDef(MI->getImplicitRef(i)); + + // iterate over MI operands to find uses + for (MachineInstr::const_val_op_iterator OpI = MI->begin(), OpE = MI->end(); + OpI != OpE; ++OpI) { + const Value *Op = *OpI; + + if (isa<BasicBlock>(Op)) + continue; // don't process labels + + if (OpI.isUse()) { // add to Uses only if this operand is a use + // + // *** WARNING: The following code for handling dummy PHI machine + // instructions is untested. The previous code was broken and I + // fixed it, but it turned out to be unused as long as Phi + // elimination is performed during instruction selection. + // + // Put Phi operands in UseSet for the incoming edge, not node. + // They must not "hide" later defs, and must be handled specially + // during set propagation over the CFG. + if (MI->getOpCode() == V9::PHI) { // for a phi node + const Value *ArgVal = Op; + const BasicBlock *PredBB = cast<BasicBlock>(*++OpI); // next ptr is BB + + PredToEdgeInSetMap[PredBB].insert(ArgVal); + + if (DEBUG_LV >= LV_DEBUG_Verbose) + std::cerr << " - phi operand " << RAV(ArgVal) << " came from BB " + << RAV(PredBB) << "\n"; + } // if( IsPhi ) + else { + // It is not a Phi use: add to regular use set and remove later defs. + addUse(Op); + } + } // if a use + } // for all operands + + // do for implicit operands as well + for (unsigned i = 0; i < MI->getNumImplicitRefs(); ++i) { + assert(MI->getOpCode() != V9::PHI && "Phi cannot have implicit operands"); + const Value *Op = MI->getImplicitRef(i); + + if (Op->getType() == Type::LabelTy) // don't process labels + continue; + + if (MI->getImplicitOp(i).isUse()) + addUse(Op); + } + } // for all machine instructions +} + + + +//----------------------------------------------------------------------------- +// To add an operand which is a def +//----------------------------------------------------------------------------- +void BBLiveVar::addDef(const Value *Op) { + DefSet.insert(Op); // operand is a def - so add to def set + InSet.erase(Op); // this definition kills any later uses + InSetChanged = true; + + if (DEBUG_LV >= LV_DEBUG_Verbose) std::cerr << " +Def: " << RAV(Op) << "\n"; +} + + +//----------------------------------------------------------------------------- +// To add an operand which is a use +//----------------------------------------------------------------------------- +void BBLiveVar::addUse(const Value *Op) { + InSet.insert(Op); // An operand is a use - so add to use set + DefSet.erase(Op); // remove if there is a def below this use + InSetChanged = true; + + if (DEBUG_LV >= LV_DEBUG_Verbose) std::cerr << " Use: " << RAV(Op) << "\n"; +} + + +//----------------------------------------------------------------------------- +// Applies the transfer function to a basic block to produce the InSet using +// the OutSet. +//----------------------------------------------------------------------------- + +bool BBLiveVar::applyTransferFunc() { + // IMPORTANT: caller should check whether the OutSet changed + // (else no point in calling) + + ValueSet OutMinusDef = set_difference(OutSet, DefSet); + InSetChanged = set_union(InSet, OutMinusDef); + + OutSetChanged = false; // no change to OutSet since transf func applied + return InSetChanged; +} + + +//----------------------------------------------------------------------------- +// calculates Out set using In sets of the successors +//----------------------------------------------------------------------------- + +bool BBLiveVar::setPropagate(ValueSet *OutSet, const ValueSet *InSet, + const BasicBlock *PredBB) { + bool Changed = false; + + // merge all members of InSet into OutSet of the predecessor + for (ValueSet::const_iterator InIt = InSet->begin(), InE = InSet->end(); + InIt != InE; ++InIt) + if ((OutSet->insert(*InIt)).second) + Changed = true; + + // + //**** WARNING: The following code for handling dummy PHI machine + // instructions is untested. See explanation above. + // + // then merge all members of the EdgeInSet for the predecessor into the OutSet + const ValueSet& EdgeInSet = PredToEdgeInSetMap[PredBB]; + for (ValueSet::const_iterator InIt = EdgeInSet.begin(), InE = EdgeInSet.end(); + InIt != InE; ++InIt) + if ((OutSet->insert(*InIt)).second) + Changed = true; + // + //**** + + return Changed; +} + + +//----------------------------------------------------------------------------- +// propagates in set to OutSets of PREDECESSORs +//----------------------------------------------------------------------------- + +bool BBLiveVar::applyFlowFunc(hash_map<const BasicBlock*, + BBLiveVar*> &BBLiveVarInfo) { + // IMPORTANT: caller should check whether inset changed + // (else no point in calling) + + // If this BB changed any OutSets of preds whose POID is lower, than we need + // another iteration... + // + bool needAnotherIt = false; + + for (pred_const_iterator PI = pred_begin(&BB), PE = pred_end(&BB); + PI != PE ; ++PI) { + BBLiveVar *PredLVBB = BBLiveVarInfo[*PI]; + + // do set union + if (setPropagate(&PredLVBB->OutSet, &InSet, *PI)) { + PredLVBB->OutSetChanged = true; + + // if the predec POID is lower than mine + if (PredLVBB->getPOId() <= POID) + needAnotherIt = true; + } + } // for + + return needAnotherIt; +} + + + +// ----------------- Methods For Debugging (Printing) ----------------- + +void BBLiveVar::printAllSets() const { + std::cerr << " Defs: "; printSet(DefSet); std::cerr << "\n"; + std::cerr << " In: "; printSet(InSet); std::cerr << "\n"; + std::cerr << " Out: "; printSet(OutSet); std::cerr << "\n"; +} + +void BBLiveVar::printInOutSets() const { + std::cerr << " In: "; printSet(InSet); std::cerr << "\n"; + std::cerr << " Out: "; printSet(OutSet); std::cerr << "\n"; +} + +} // End llvm namespace diff --git a/llvm/lib/Target/Sparc/LiveVar/BBLiveVar.h b/llvm/lib/Target/Sparc/LiveVar/BBLiveVar.h new file mode 100644 index 00000000000..781143a93df --- /dev/null +++ b/llvm/lib/Target/Sparc/LiveVar/BBLiveVar.h @@ -0,0 +1,90 @@ +//===-- BBLiveVar.h - Live Variable Analysis for a BasicBlock ---*- C++ -*-===// +// +// 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 is a BasicBlock annotation class that is used by live var analysis to +// hold data flow information for a basic block. +// +//===----------------------------------------------------------------------===// + +#ifndef LIVE_VAR_BB_H +#define LIVE_VAR_BB_H + +#include "llvm/CodeGen/ValueSet.h" +#include "Support/hash_map" + +namespace llvm { + +class BasicBlock; +class Value; +class MachineBasicBlock; + +enum LiveVarDebugLevel_t { + LV_DEBUG_None, + LV_DEBUG_Normal, + LV_DEBUG_Instr, + LV_DEBUG_Verbose +}; + +extern LiveVarDebugLevel_t DEBUG_LV; + +class BBLiveVar { + const BasicBlock &BB; // pointer to BasicBlock + MachineBasicBlock &MBB; // Pointer to MachineBasicBlock + unsigned POID; // Post-Order ID + + ValueSet DefSet; // Def set (with no preceding uses) for LV analysis + ValueSet InSet, OutSet; // In & Out for LV analysis + bool InSetChanged, OutSetChanged; // set if the InSet/OutSet is modified + + // map that contains PredBB -> Phi arguments + // coming in on that edge. such uses have to be + // treated differently from ordinary uses. + hash_map<const BasicBlock *, ValueSet> PredToEdgeInSetMap; + + // method to propagate an InSet to OutSet of a predecessor + bool setPropagate(ValueSet *OutSetOfPred, + const ValueSet *InSetOfThisBB, + const BasicBlock *PredBB); + + // To add an operand which is a def + void addDef(const Value *Op); + + // To add an operand which is a use + void addUse(const Value *Op); + + void calcDefUseSets(); // calculates the Def & Use sets for this BB +public: + + BBLiveVar(const BasicBlock &BB, MachineBasicBlock &MBB, unsigned POID); + + inline bool isInSetChanged() const { return InSetChanged; } + inline bool isOutSetChanged() const { return OutSetChanged; } + + MachineBasicBlock &getMachineBasicBlock() const { return MBB; } + + inline unsigned getPOId() const { return POID; } + + bool applyTransferFunc(); // calcultes the In in terms of Out + + // calculates Out set using In sets of the predecessors + bool applyFlowFunc(hash_map<const BasicBlock*, BBLiveVar*> &BBLiveVarInfo); + + inline const ValueSet &getOutSet() const { return OutSet; } + inline ValueSet &getOutSet() { return OutSet; } + + inline const ValueSet &getInSet() const { return InSet; } + inline ValueSet &getInSet() { return InSet; } + + void printAllSets() const; // for printing Def/In/Out sets + void printInOutSets() const; // for printing In/Out sets +}; + +} // End llvm namespace + +#endif diff --git a/llvm/lib/Target/Sparc/LiveVar/FunctionLiveVarInfo.cpp b/llvm/lib/Target/Sparc/LiveVar/FunctionLiveVarInfo.cpp new file mode 100644 index 00000000000..e342760f723 --- /dev/null +++ b/llvm/lib/Target/Sparc/LiveVar/FunctionLiveVarInfo.cpp @@ -0,0 +1,322 @@ +//===-- FunctionLiveVarInfo.cpp - Live Variable Analysis for a 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. +// +//===----------------------------------------------------------------------===// +// +// This is the interface to function level live variable information that is +// provided by live variable analysis. +// +//===----------------------------------------------------------------------===// + +#include "llvm/CodeGen/FunctionLiveVarInfo.h" +#include "llvm/CodeGen/MachineInstr.h" +#include "llvm/CodeGen/MachineFunction.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetInstrInfo.h" +#include "llvm/Support/CFG.h" +#include "Support/PostOrderIterator.h" +#include "Support/SetOperations.h" +#include "Support/CommandLine.h" +#include "BBLiveVar.h" + +namespace llvm { + +static RegisterAnalysis<FunctionLiveVarInfo> +X("livevar", "Live Variable Analysis"); + +LiveVarDebugLevel_t DEBUG_LV; + +static cl::opt<LiveVarDebugLevel_t, true> +DEBUG_LV_opt("dlivevar", cl::Hidden, cl::location(DEBUG_LV), + cl::desc("enable live-variable debugging information"), + cl::values( +clEnumValN(LV_DEBUG_None , "n", "disable debug output"), +clEnumValN(LV_DEBUG_Normal , "y", "enable debug output"), +clEnumValN(LV_DEBUG_Instr, "i", "print live-var sets before/after " + "every machine instrn"), +clEnumValN(LV_DEBUG_Verbose, "v", "print def, use sets for every instrn also"), + 0)); + + + +//----------------------------------------------------------------------------- +// Accessor Functions +//----------------------------------------------------------------------------- + +// gets OutSet of a BB +const ValueSet &FunctionLiveVarInfo::getOutSetOfBB(const BasicBlock *BB) const { + return BBLiveVarInfo.find(BB)->second->getOutSet(); +} + ValueSet &FunctionLiveVarInfo::getOutSetOfBB(const BasicBlock *BB) { + return BBLiveVarInfo[BB]->getOutSet(); +} + +// gets InSet of a BB +const ValueSet &FunctionLiveVarInfo::getInSetOfBB(const BasicBlock *BB) const { + return BBLiveVarInfo.find(BB)->second->getInSet(); +} +ValueSet &FunctionLiveVarInfo::getInSetOfBB(const BasicBlock *BB) { + return BBLiveVarInfo[BB]->getInSet(); +} + + +//----------------------------------------------------------------------------- +// Performs live var analysis for a function +//----------------------------------------------------------------------------- + +bool FunctionLiveVarInfo::runOnFunction(Function &F) { + M = &F; + if (DEBUG_LV) std::cerr << "Analysing live variables ...\n"; + + // create and initialize all the BBLiveVars of the CFG + constructBBs(M); + + unsigned int iter=0; + while (doSingleBackwardPass(M, iter++)) + ; // Iterate until we are done. + + if (DEBUG_LV) std::cerr << "Live Variable Analysis complete!\n"; + return false; +} + + +//----------------------------------------------------------------------------- +// constructs BBLiveVars and init Def and In sets +//----------------------------------------------------------------------------- + +void FunctionLiveVarInfo::constructBBs(const Function *F) { + unsigned POId = 0; // Reverse Depth-first Order ID + std::map<const BasicBlock*, unsigned> PONumbering; + + for (po_iterator<const Function*> BBI = po_begin(M), BBE = po_end(M); + BBI != BBE; ++BBI) + PONumbering[*BBI] = POId++; + + MachineFunction &MF = MachineFunction::get(F); + for (MachineFunction::iterator I = MF.begin(), E = MF.end(); I != E; ++I) { + const BasicBlock &BB = *I->getBasicBlock(); // get the current BB + if (DEBUG_LV) std::cerr << " For BB " << RAV(BB) << ":\n"; + + BBLiveVar *LVBB; + std::map<const BasicBlock*, unsigned>::iterator POI = PONumbering.find(&BB); + if (POI != PONumbering.end()) { + // create a new BBLiveVar + LVBB = new BBLiveVar(BB, *I, POId); + } else { + // The PO iterator does not discover unreachable blocks, but the random + // iterator later may access these blocks. We must make sure to + // initialize unreachable blocks as well. However, LV info is not correct + // for those blocks (they are not analyzed) + // + LVBB = new BBLiveVar(BB, *I, ++POId); + } + BBLiveVarInfo[&BB] = LVBB; + + if (DEBUG_LV) + LVBB->printAllSets(); + } +} + + +//----------------------------------------------------------------------------- +// do one backward pass over the CFG (for iterative analysis) +//----------------------------------------------------------------------------- + +bool FunctionLiveVarInfo::doSingleBackwardPass(const Function *M, + unsigned iter) { + if (DEBUG_LV) std::cerr << "\n After Backward Pass " << iter << "...\n"; + + bool NeedAnotherIteration = false; + for (po_iterator<const Function*> BBI = po_begin(M), BBE = po_end(M); + BBI != BBE; ++BBI) { + BBLiveVar *LVBB = BBLiveVarInfo[*BBI]; + assert(LVBB && "BasicBlock information not set for block!"); + + if (DEBUG_LV) std::cerr << " For BB " << (*BBI)->getName() << ":\n"; + + // InSets are initialized to "GenSet". Recompute only if OutSet changed. + if(LVBB->isOutSetChanged()) + LVBB->applyTransferFunc(); // apply the Tran Func to calc InSet + + // OutSets are initialized to EMPTY. Recompute on first iter or if InSet + // changed. + if (iter == 0 || LVBB->isInSetChanged()) // to calc Outsets of preds + NeedAnotherIteration |= LVBB->applyFlowFunc(BBLiveVarInfo); + + if (DEBUG_LV) LVBB->printInOutSets(); + } + + // true if we need to reiterate over the CFG + return NeedAnotherIteration; +} + + +void FunctionLiveVarInfo::releaseMemory() { + // First remove all BBLiveVars created in constructBBs(). + if (M) { + for (Function::const_iterator I = M->begin(), E = M->end(); I != E; ++I) + delete BBLiveVarInfo[I]; + BBLiveVarInfo.clear(); + } + M = 0; + + // Then delete all objects of type ValueSet created in calcLiveVarSetsForBB + // and entered into MInst2LVSetBI and MInst2LVSetAI (these are caches + // to return ValueSet's before/after a machine instruction quickly). + // We do not need to free up ValueSets in MInst2LVSetAI because it holds + // pointers to the same sets as in MInst2LVSetBI (for all instructions + // except the last one in a BB) or in BBLiveVar (for the last instruction). + // + for (hash_map<const MachineInstr*, ValueSet*>::iterator + MI = MInst2LVSetBI.begin(), + ME = MInst2LVSetBI.end(); MI != ME; ++MI) + delete MI->second; // delete all ValueSets in MInst2LVSetBI + + MInst2LVSetBI.clear(); + MInst2LVSetAI.clear(); +} + + + + +//----------------------------------------------------------------------------- +// Following functions will give the LiveVar info for any machine instr in +// a function. It should be called after a call to analyze(). +// +// These functions calculate live var info for all the machine instrs in a +// BB when LVInfo for one inst is requested. Hence, this function is useful +// when live var info is required for many (or all) instructions in a basic +// block. Also, the arguments to this function does not require specific +// iterators. +//----------------------------------------------------------------------------- + +//----------------------------------------------------------------------------- +// Gives live variable information before a machine instruction +//----------------------------------------------------------------------------- + +const ValueSet & +FunctionLiveVarInfo::getLiveVarSetBeforeMInst(const MachineInstr *MI, + const BasicBlock *BB) { + ValueSet* &LVSet = MInst2LVSetBI[MI]; // ref. to map entry + if (LVSet == NULL && BB != NULL) { // if not found and BB provided + calcLiveVarSetsForBB(BB); // calc LVSet for all instrs in BB + assert(LVSet != NULL); + } + return *LVSet; +} + + +//----------------------------------------------------------------------------- +// Gives live variable information after a machine instruction +//----------------------------------------------------------------------------- + +const ValueSet & +FunctionLiveVarInfo::getLiveVarSetAfterMInst(const MachineInstr *MI, + const BasicBlock *BB) { + + ValueSet* &LVSet = MInst2LVSetAI[MI]; // ref. to map entry + if (LVSet == NULL && BB != NULL) { // if not found and BB provided + calcLiveVarSetsForBB(BB); // calc LVSet for all instrs in BB + assert(LVSet != NULL); + } + return *LVSet; +} + +// This function applies a machine instr to a live var set (accepts OutSet) and +// makes necessary changes to it (produces InSet). Note that two for loops are +// used to first kill all defs and then to add all uses. This is because there +// can be instructions like Val = Val + 1 since we allow multiple defs to a +// machine instruction operand. +// +static void applyTranferFuncForMInst(ValueSet &LVS, const MachineInstr *MInst) { + for (MachineInstr::const_val_op_iterator OpI = MInst->begin(), + OpE = MInst->end(); OpI != OpE; ++OpI) { + if (OpI.isDef()) // kill if this operand is a def + LVS.erase(*OpI); // this definition kills any uses + } + + // do for implicit operands as well + for (unsigned i=0; i < MInst->getNumImplicitRefs(); ++i) { + if (MInst->getImplicitOp(i).isDef()) + LVS.erase(MInst->getImplicitRef(i)); + } + + for (MachineInstr::const_val_op_iterator OpI = MInst->begin(), + OpE = MInst->end(); OpI != OpE; ++OpI) { + if (!isa<BasicBlock>(*OpI)) // don't process labels + // add only if this operand is a use + if (OpI.isUse()) + LVS.insert(*OpI); // An operand is a use - so add to use set + } + + // do for implicit operands as well + for (unsigned i = 0, e = MInst->getNumImplicitRefs(); i != e; ++i) + if (MInst->getImplicitOp(i).isUse()) + LVS.insert(MInst->getImplicitRef(i)); +} + +//----------------------------------------------------------------------------- +// This method calculates the live variable information for all the +// instructions in a basic block and enter the newly constructed live +// variable sets into a the caches (MInst2LVSetAI, MInst2LVSetBI) +//----------------------------------------------------------------------------- + +void FunctionLiveVarInfo::calcLiveVarSetsForBB(const BasicBlock *BB) { + BBLiveVar *BBLV = BBLiveVarInfo[BB]; + assert(BBLV && "BBLiveVar annotation doesn't exist?"); + const MachineBasicBlock &MIVec = BBLV->getMachineBasicBlock(); + const MachineFunction &MF = MachineFunction::get(M); + const TargetMachine &TM = MF.getTarget(); + + if (DEBUG_LV >= LV_DEBUG_Instr) + std::cerr << "\n======For BB " << BB->getName() + << ": Live var sets for instructions======\n"; + + ValueSet *SetAI = &getOutSetOfBB(BB); // init SetAI with OutSet + ValueSet CurSet(*SetAI); // CurSet now contains OutSet + + // iterate over all the machine instructions in BB + for (MachineBasicBlock::const_reverse_iterator MII = MIVec.rbegin(), + MIE = MIVec.rend(); MII != MIE; ++MII) { + // MI is cur machine inst + const MachineInstr *MI = *MII; + + MInst2LVSetAI[MI] = SetAI; // record in After Inst map + + applyTranferFuncForMInst(CurSet, MI); // apply the transfer Func + ValueSet *NewSet = new ValueSet(CurSet); // create a new set with a copy + // of the set after T/F + MInst2LVSetBI[MI] = NewSet; // record in Before Inst map + + // If the current machine instruction has delay slots, mark values + // used by this instruction as live before and after each delay slot + // instruction (After(MI) is the same as Before(MI+1) except for last MI). + if (unsigned DS = TM.getInstrInfo().getNumDelaySlots(MI->getOpCode())) { + MachineBasicBlock::const_iterator fwdMII = MII.base(); // ptr to *next* MI + for (unsigned i = 0; i < DS; ++i, ++fwdMII) { + assert(fwdMII != MIVec.end() && "Missing instruction in delay slot?"); + MachineInstr* DelaySlotMI = *fwdMII; + if (! TM.getInstrInfo().isNop(DelaySlotMI->getOpCode())) { + set_union(*MInst2LVSetBI[DelaySlotMI], *NewSet); + if (i+1 == DS) + set_union(*MInst2LVSetAI[DelaySlotMI], *NewSet); + } + } + } + + if (DEBUG_LV >= LV_DEBUG_Instr) { + std::cerr << "\nLive var sets before/after instruction " << *MI; + std::cerr << " Before: "; printSet(*NewSet); std::cerr << "\n"; + std::cerr << " After : "; printSet(*SetAI); std::cerr << "\n"; + } + + // SetAI will be used in the next iteration + SetAI = NewSet; + } +} + +} // End llvm namespace diff --git a/llvm/lib/Target/Sparc/LiveVar/Makefile b/llvm/lib/Target/Sparc/LiveVar/Makefile new file mode 100644 index 00000000000..90a664e56ce --- /dev/null +++ b/llvm/lib/Target/Sparc/LiveVar/Makefile @@ -0,0 +1,14 @@ +##===- lib/Target/Sparc/LiveVar/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 = livevar + +include $(LEVEL)/Makefile.common + diff --git a/llvm/lib/Target/Sparc/LiveVar/ValueSet.cpp b/llvm/lib/Target/Sparc/LiveVar/ValueSet.cpp new file mode 100644 index 00000000000..fd8289675a2 --- /dev/null +++ b/llvm/lib/Target/Sparc/LiveVar/ValueSet.cpp @@ -0,0 +1,31 @@ +// +// 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. +// +//===----------------------------------------------------------------------===// +// FIXME: Eliminate this file. + +#include "llvm/CodeGen/ValueSet.h" +#include "llvm/Value.h" +#include <iostream> + +namespace llvm { + +std::ostream &operator<<(std::ostream &O, RAV V) { // func to print a Value + const Value &v = V.V; + if (v.hasName()) + return O << (void*)&v << "(" << v.getName() << ") "; + else if (isa<Constant>(v)) + return O << (void*)&v << "(" << v << ") "; + else + return O << (void*)&v << " "; +} + +void printSet(const ValueSet &S) { + for (ValueSet::const_iterator I = S.begin(), E = S.end(); I != E; ++I) + std::cerr << RAV(*I); +} + +} // End llvm namespace diff --git a/llvm/lib/Target/Sparc/Makefile b/llvm/lib/Target/Sparc/Makefile index cf61657d753..619c9d02e7c 100644 --- a/llvm/lib/Target/Sparc/Makefile +++ b/llvm/lib/Target/Sparc/Makefile @@ -8,7 +8,7 @@ ##===----------------------------------------------------------------------===## LEVEL = ../../.. LIBRARYNAME = sparc -DIRS = InstrSelection RegAlloc +DIRS = InstrSelection RegAlloc LiveVar ExtraSource = Sparc.burm.cpp |