OpenASIP  2.0
Classes | Public Member Functions | Protected Types | Protected Member Functions | Protected Attributes | Static Protected Attributes | List of all members
DataDependenceGraphBuilder Class Reference

#include <DataDependenceGraphBuilder.hh>

Inheritance diagram for DataDependenceGraphBuilder:
Inheritance graph
Collaboration diagram for DataDependenceGraphBuilder:
Collaboration graph

Classes

struct  BBData
 

Public Member Functions

 DataDependenceGraphBuilder ()
 
 DataDependenceGraphBuilder (InterPassData &ipd)
 
virtual ~DataDependenceGraphBuilder ()
 
void addAliasAnalyzer (MemoryAliasAnalyzer *analyzer)
 
virtual DataDependenceGraphbuild (ControlFlowGraph &cGraph, DataDependenceGraph::AntidependenceLevel antidependenceLevel, const TTAMachine::Machine &mach, const UniversalMachine *um=NULL, bool createMemAndFUDeps=true, bool createDeathInformation=true, llvm::AliasAnalysis *AA=NULL)
 
virtual DataDependenceGraphbuild (TTAProgram::BasicBlock &bb, DataDependenceGraph::AntidependenceLevel antidependenceLevel, const TTAMachine::Machine &mach, const TCEString &ddgname="small bb", const UniversalMachine *um=NULL, bool createMemAndFUDeps=true, llvm::AliasAnalysis *AA=NULL)
 

Protected Types

enum  BBState { BB_UNREACHED = 0, BB_QUEUED, BB_READY, BB_STATES }
 
enum  ConstructionPhase { REGISTERS_AND_PROGRAM_OPERATIONS = 0, MEMORY_AND_SIDE_EFFECTS }
 
typedef ControlFlowGraph::NodeSet BasicBlockNodeSet
 
typedef DataDependenceGraph::NodeSet MNodeSet
 
typedef LiveRangeData::MoveNodeUseSet MoveNodeUseSet
 
typedef LiveRangeData::MoveNodeUseMapSet MoveNodeUseMapSet
 
typedef LiveRangeData::MoveNodeUseMap MoveNodeUseMap
 
typedef LiveRangeData::MoveNodeUseSetPair MoveNodeUseSetPair
 
typedef LiveRangeData::MoveNodeUsePair MoveNodeUsePair
 
typedef std::map< int, TCEStringSpecialRegisters
 
typedef std::vector< MemoryAliasAnalyzer * > AliasAnalyzerVector
 
typedef std::map< BasicBlockNode *, BBData * > BBDataMap
 
typedef std::list< BBData * > BBDataList
 

Protected Member Functions

bool isTriggering (const MoveNode &mn)
 
void updatePreceedingRegistersUsedAfter (BBData &bbd, bool firstTime)
 
bool updateRegistersUsedInOrAfter (BBData &bbd)
 
bool updateRegistersAliveAfter (BBData &bbd)
 
bool updateMemAndFuAliveAfter (BBData &bbd)
 
void createMemAndFUstateDeps ()
 
void createRegisterDeps ()
 
void initializeBBStates ()
 
BasicBlockNodequeueFirstBB ()
 
void clearUnneededBookkeeping ()
 
void clearUnneededBookkeeping (TTAProgram::BasicBlock &bb, bool aliveInformationNeeded=true)
 
void iterateBBs (ConstructionPhase phase)
 
void searchRegisterDeaths ()
 
void iterateRegisterDeaths ()
 
void setSucceedingPredeps (BBData &bbd, bool queueAll, ConstructionPhase phase)
 
bool appendUseMapSets (const MoveNodeUseMapSet &srcMap, MoveNodeUseMapSet &dstMap, bool addLoopProperty)
 
void setSucceedingPredepsForBB (TTAProgram::BasicBlock &processedBB, BasicBlockNode &successor, bool queueAll, bool loop, ConstructionPhase phase)
 
void updateBB (BBData &bbd, ConstructionPhase phase)
 
void constructIndividualBB (ConstructionPhase phase)
 
void constructIndividualFromInlineAsmBB (ConstructionPhase phase)
 
void constructIndividualBB (BBData &bbd, ConstructionPhase)
 
void constructBB (BasicBlockNodeSet &inputBlocks)
 
void createOperationEdges (ProgramOperationPtr po)
 
void processGuard (MoveNode &moveNode)
 
void processSource (MoveNode &moveNode)
 
void processResultRead (MoveNode &moveNode)
 
void processCall (MoveNode &mn)
 
void processReturn (MoveNode &moveNode)
 
void processEntryNode (MoveNode &mn)
 
void processDestination (class MoveNode &moveNode, ConstructionPhase phase)
 
void processRegUse (MoveNodeUse mn, const TCEString &reg)
 
void updateMemUse (MoveNodeUse mnd, const TCEString &category)
 
void processRegWrite (MoveNodeUse mn, const TCEString &reg)
 
void updateMemWrite (MoveNodeUse mnd, const TCEString &category)
 
void processTriggerPO (class MoveNode &moveNode, Operation &dop)
 
void processTriggerRegistersAndOperations (MoveNode &moveNode, Operation &dop)
 
void processTriggerMemoryAndFUStates (MoveNode &moveNode, Operation &dop)
 
void createTriggerDependencies (class MoveNode &moveNode, class Operation &dop)
 
void createSideEffectEdges (MoveNodeUseSet &prevMoves, const MoveNode &mn, Operation &dop)
 
void processMemWrite (MoveNodeUse mnd)
 
void processMemUse (MoveNodeUse mnd)
 
void processOperand (class MoveNode &moveNode, Operation &dop)
 
MemoryAliasAnalyzer::AliasingResult analyzeMemoryAlias (const ProgramOperation &pop1, const ProgramOperation &pop2, MoveNodeUse::BBRelation bbInfo)
 
bool isAddressTraceable (const ProgramOperation &pop)
 
TCEString memoryCategory (const MoveNodeUse &mnd)
 
bool checkAndCreateMemDep (MoveNodeUse prev, MoveNodeUse mnd, DataDependenceEdge::DependenceType depType)
 
void checkAndCreateMemAntideps (MoveNodeUse &mnd, std::set< MoveNodeUse > &prevNodes, DataDependenceEdge::DependenceType depType, bool traceable)
 
bool hasEarlierMemWriteToSameAddressWithSameGuard (MoveNodeUse &mnd, std::set< MoveNodeUse > &defines)
 
std::set< MoveNodeUseearlierWritesWithSameGuard (MoveNodeUse &mnd, std::set< MoveNodeUse > &defines)
 
bool hasEarlierWriteWithSameGuard (MoveNodeUse &mnd, std::set< MoveNodeUse > &defines)
 
void createRegisterAntideps (const TCEString &reg, MoveNodeUse &mnd, MoveNodeUseSet &predecessorNodes, DataDependenceEdge::DependenceType depType, bool guardedKillFound)
 
void changeState (BBData &bbd, BBState newState, bool priorize=false)
 
bool isAlwaysDifferentFU (const MoveNode *srcMN, const MoveNode *dstMN)
 
void findStaticRegisters (TTAProgram::CodeSnippet &cs, std::map< int, TCEString > &registers)
 find special register data from old frontend code More...
 
void findStaticRegisters (ControlFlowGraph &cfg, std::map< int, TCEString > &registers)
 
void findStaticRegisters (TTAProgram::Instruction &ins, std::map< int, TCEString > &registers)
 
void findStaticRegisters (const UniversalMachine &um, std::map< int, TCEString > &registers)
 
void appendMoveNodeUse (const LiveRangeData::MoveNodeUseSet &src, LiveRangeData::MoveNodeUseSet &dst, bool setLoopProperty)
 

Protected Attributes

std::set< TCEStringallParamRegs_
 
BBDataList blocksByState_ [BB_STATES]
 
BBDataMap bbData_
 
BasicBlockNodecurrentBB_
 
BBDatacurrentData_
 
DataDependenceGraphcurrentDDG_
 
AliasAnalyzerVector aliasAnalyzers_
 
SpecialRegisters specialRegisters_
 contains stack pointer, RV and parameter registers. More...
 
InterPassDatainterPassData_
 
ControlFlowGraphcfg_
 
bool rvIsParamReg_
 
const TTAMachine::Machinemach_
 

Static Protected Attributes

static const TCEString RA_NAME = "RA"
 

Detailed Description

DataDependenceGraphBuilder class is responsible for building data dependence graphs.

Definition at line 70 of file DataDependenceGraphBuilder.hh.

Member Typedef Documentation

◆ AliasAnalyzerVector

Definition at line 112 of file DataDependenceGraphBuilder.hh.

◆ BasicBlockNodeSet

Definition at line 102 of file DataDependenceGraphBuilder.hh.

◆ BBDataList

typedef std::list<BBData*> DataDependenceGraphBuilder::BBDataList
protected

Definition at line 144 of file DataDependenceGraphBuilder.hh.

◆ BBDataMap

Definition at line 143 of file DataDependenceGraphBuilder.hh.

◆ MNodeSet

Definition at line 103 of file DataDependenceGraphBuilder.hh.

◆ MoveNodeUseMap

Definition at line 107 of file DataDependenceGraphBuilder.hh.

◆ MoveNodeUseMapSet

Definition at line 106 of file DataDependenceGraphBuilder.hh.

◆ MoveNodeUsePair

Definition at line 109 of file DataDependenceGraphBuilder.hh.

◆ MoveNodeUseSet

Definition at line 105 of file DataDependenceGraphBuilder.hh.

◆ MoveNodeUseSetPair

Definition at line 108 of file DataDependenceGraphBuilder.hh.

◆ SpecialRegisters

typedef std::map<int, TCEString> DataDependenceGraphBuilder::SpecialRegisters
protected

Definition at line 111 of file DataDependenceGraphBuilder.hh.

Member Enumeration Documentation

◆ BBState

Enumerator
BB_UNREACHED 
BB_QUEUED 

Basic block we have not yet encountered.

BB_READY 

BB which is queued to be processed.

BB_STATES 

BB which is already processed and is not queued.

Definition at line 114 of file DataDependenceGraphBuilder.hh.

114  {
115  BB_UNREACHED = 0, /// Basic block we have not yet encountered.
116  BB_QUEUED, /// BB which is queued to be processed
117  BB_READY, ///BB which is already processed and is not queued.
118  BB_STATES};

◆ ConstructionPhase

Enumerator
REGISTERS_AND_PROGRAM_OPERATIONS 
MEMORY_AND_SIDE_EFFECTS 

Definition at line 120 of file DataDependenceGraphBuilder.hh.

Constructor & Destructor Documentation

◆ DataDependenceGraphBuilder() [1/2]

POP_COMPILER_DIAGS DataDependenceGraphBuilder::DataDependenceGraphBuilder ( )

Constructor of Data Dependence graph builder.

This constructor does not take special registers from interpass data, so it must analyze them from the code annotations. Used with old frontend.

constant alias AA check aa between global variables.

Definition at line 118 of file DataDependenceGraphBuilder.cc.

118  :
119  interPassData_(NULL), cfg_(NULL), rvIsParamReg_(false) {
120 
121  /// constant alias AA check aa between global variables.
123 
124 #ifdef USE_FALSE_AA
125  /// defining USE_FALSE_AA results in faster but
126  /// broken code. just for testing theoretical benefits.
128 #endif
130 
131  LLVMTCECmdLineOptions* llvmOptions =
132  dynamic_cast<LLVMTCECmdLineOptions*>(
134  if (llvmOptions != NULL && llvmOptions->disableLLVMAA() == false) {
136  }
137 }

References addAliasAnalyzer(), Application::cmdLineOptions(), and LLVMTCECmdLineOptions::disableLLVMAA().

Here is the call graph for this function:

◆ DataDependenceGraphBuilder() [2/2]

DataDependenceGraphBuilder::DataDependenceGraphBuilder ( InterPassData ipd)

Constructor of Data Dependence graph builder.

This constructor takes special registers from interpass data.

Definition at line 145 of file DataDependenceGraphBuilder.cc.

145  :
146  // TODO: when param reg thing works, rvIsParamReg becomes true here
147  interPassData_(&ipd), cfg_(NULL), rvIsParamReg_(true) {
148 
149  // Need to store data about special registers which have semantics
150  // between function calls and exits. These are stack pointer,
151  // return value register and the secondary "hi bits"
152  // return value register.
153 
154  static const TCEString SP_DATUM = "STACK_POINTER";
155  static const TCEString FP_DATUM = "FRAME_POINTER";
156  static const TCEString RV_DATUM = "RV_REGISTER";
157  // high part of 64-bit return values.
158  static const TCEString RV_HIGH_DATUM = "RV_HIGH_REGISTER";
159 
160  static const TCEString IPARAM_DATUM_PREFIX = "IPARAM";
161  static const TCEString VECTOR_RV_PREFIX="VRV_REGISTER";
162 
164  dynamic_cast<SchedulerCmdLineOptions*>(
166 
167  if (ipd.hasDatum(SP_DATUM)) {
168  RegDatum& sp = dynamic_cast<RegDatum&>(ipd.datum(SP_DATUM));
169  TCEString spName = sp.first + '.' + Conversion::toString(sp.second);
170  specialRegisters_[REG_SP] = spName;
171 
172  // create stack alias analyzer if enabled.
173  if ((options != NULL && options->enableStackAA())) {
175  }
176 
177  if (options != NULL && options->enableOffsetAA()) {
179  }
180 
181  addAliasAnalyzer(new GlobalVsStackAA(spName));
182 
183  } else {
187  << "Warning: Stack pointer datum not found "
188  << "in interpassdata given to ddg builder. "
189  << "May generate invalid code if stack used."
190  << std::endl;
191  }
192  }
193 
194  if (ipd.hasDatum(RV_DATUM)) {
195  RegDatum& rv = dynamic_cast<RegDatum&>(ipd.datum(RV_DATUM));
196  TCEString reg = rv.first + '.' + Conversion::toString(rv.second);
197  specialRegisters_[REG_RV] = reg;
198  if (rvIsParamReg_) {
199  allParamRegs_.insert(reg);
200  }
201 
202  } else {
206  << "Warning: Return value register datum not found "
207  << "in interpassdata given to ddg builder. "
208  << "May generate invalid code if return values used."
209  << std::endl;
210  }
211  }
212 
213  for(int i = 2;;i++) {
214  TCEString datum = IPARAM_DATUM_PREFIX; datum << i;
215  if (ipd.hasDatum(datum)) {
216  RegDatum& p = dynamic_cast<RegDatum&>(ipd.datum(datum));
217  TCEString reg = p.first + '.' + Conversion::toString(p.second);
218  specialRegisters_[REG_IPARAM+i-1] = reg;
219  } else {
220  break;
221  }
222  }
223 
224  for (int i = 0;;i++) {
225  TCEString datum = VECTOR_RV_PREFIX; datum << i;
226  if (ipd.hasDatum(datum)) {
227  RegDatum& p = dynamic_cast<RegDatum&>(ipd.datum(datum));
228  TCEString reg = p.first + '.' + Conversion::toString(p.second);
229  specialRegisters_[REG_VRV-i] = reg;
230  } else {
231  break;
232  }
233 
234  }
235 
236  if (ipd.hasDatum(FP_DATUM)) {
237  RegDatum& fp = dynamic_cast<RegDatum&>(ipd.datum(FP_DATUM));
238  TCEString reg = fp.first + '.' + Conversion::toString(fp.second);
239  specialRegisters_[REG_FP] = reg;
240  } else {
244  << "Warning: Frame Pointer Register datum not found "
245  << "in interpassdata given to ddg builder. "
246  << "May generate invalid code."
247  << std::endl;
248  }
249  }
250 
251  if (ipd.hasDatum(RV_HIGH_DATUM)) {
252  RegDatum& rvh = dynamic_cast<RegDatum&>(ipd.datum(RV_HIGH_DATUM));
254  rvh.first + '.' + Conversion::toString(rvh.second);
255  }
256 
257  // constant alias AA check aa between global variables.
259 
260  LLVMTCECmdLineOptions* llvmOptions =
261  dynamic_cast<LLVMTCECmdLineOptions*>(
263  if (llvmOptions != NULL && llvmOptions->disableLLVMAA() == false) {
265  }
267 
268 #ifdef USE_FALSE_AA
269  /// defining USE_FALSE_AA results in faster but
270  /// broken code. just for testing theoretical benefits.
272 #else
273  if ((options != NULL && options->noaliasFunctions() &&
274  !options->noaliasFunctions()->empty())) {
275  addAliasAnalyzer(new FalseAliasAnalyzer(options->noaliasFunctions()));
276  }
277 #endif
278 }

References addAliasAnalyzer(), allParamRegs_, Application::cmdLineOptions(), InterPassData::datum(), LLVMTCECmdLineOptions::disableLLVMAA(), InterPassData::hasDatum(), Application::logStream(), options, REG_FP, REG_IPARAM, REG_RV, REG_RV_HIGH, REG_SP, REG_VRV, rvIsParamReg_, specialRegisters_, Conversion::toString(), Application::VERBOSE_LEVEL_DEFAULT, and Application::verboseLevel().

Here is the call graph for this function:

◆ ~DataDependenceGraphBuilder()

DataDependenceGraphBuilder::~DataDependenceGraphBuilder ( )
virtual

Destructor of DataDependenceGraphBuilder

Definition at line 283 of file DataDependenceGraphBuilder.cc.

References aliasAnalyzers_, and SequenceTools::deleteAllItems().

Here is the call graph for this function:

Member Function Documentation

◆ addAliasAnalyzer()

void DataDependenceGraphBuilder::addAliasAnalyzer ( MemoryAliasAnalyzer analyzer)

Adds a memory alias analyzer to the DDG builder.

Parameters
analyzerobject which will analyze memory accesses.

Definition at line 293 of file DataDependenceGraphBuilder.cc.

293  {
294  aliasAnalyzers_.push_back(analyzer);
295 }

References aliasAnalyzers_.

Referenced by DataDependenceGraphBuilder().

◆ analyzeMemoryAlias()

MemoryAliasAnalyzer::AliasingResult DataDependenceGraphBuilder::analyzeMemoryAlias ( const ProgramOperation pop1,
const ProgramOperation pop2,
MoveNodeUse::BBRelation  bbInfo 
)
protected

Gets the address-writing move of a move which is a trigger or operand to a memory operation.

If none found, return null

Parameters
mnmoveNode whose address write move is being searched.
Returns
MoveNode which writes address to a mem operation or NULL.

MoveNode* DataDependenceGraphBuilder::addressMove(const MoveNode& mn) { if (mn.isDestinationOperation()) { return addressOperandMove(mn.destinationOperation()); } return NULL; } Delegates the call to all registered memory address alias analyzers.

Returns the first non-unknown result. If no alias analyzer can analyze these, returns ALIAS_UNKNOWN

Returns
Whether the memory accesses in the given moves alias.

Definition at line 1951 of file DataDependenceGraphBuilder.cc.

1953  {
1954 
1955  for (unsigned int i = 0; i < aliasAnalyzers_.size(); i++) {
1956  MemoryAliasAnalyzer* analyzer = aliasAnalyzers_[i];
1958  analyzer->analyze(*currentDDG_, pop1, pop2, bbInfo);
1960  return res;
1961  }
1962  }
1964 }

References MemoryAliasAnalyzer::ALIAS_UNKNOWN, aliasAnalyzers_, MemoryAliasAnalyzer::analyze(), and currentDDG_.

Referenced by checkAndCreateMemDep(), hasEarlierMemWriteToSameAddressWithSameGuard(), and updateMemAndFuAliveAfter().

Here is the call graph for this function:

◆ appendMoveNodeUse()

void DataDependenceGraphBuilder::appendMoveNodeUse ( const LiveRangeData::MoveNodeUseSet src,
LiveRangeData::MoveNodeUseSet dst,
bool  setLoopProperty 
)
protected

◆ appendUseMapSets()

bool DataDependenceGraphBuilder::appendUseMapSets ( const MoveNodeUseMapSet srcMap,
MoveNodeUseMapSet dstMap,
bool  addLoopProperty 
)
protected

◆ build() [1/2]

DataDependenceGraph * DataDependenceGraphBuilder::build ( ControlFlowGraph cfg,
DataDependenceGraph::AntidependenceLevel  antidependenceLevel,
const TTAMachine::Machine mach,
const UniversalMachine um = NULL,
bool  createMemAndFUDeps = true,
bool  createDeathInformation = true,
llvm::AliasAnalysis AA = NULL 
)
virtual

Builds a DDG from a CFG.

Parameters
cfgControl flow graph where the ddg is built from.
antidependenceLevellevel of register antidependencies to create.
umuniversalmachine used for the code if registers unallocated. if null, assumed that registers allready allocated.
createMemAndFUDepswhether to create also memory and fu state(side effect) dependencies or only register deps.
createDeathInformationwhether to search the last usage of all liveranges. This is needed for things like register renamer and threading.
Returns
pointer to the ddg which is created.

Definition at line 2120 of file DataDependenceGraphBuilder.cc.

2126  {
2127 
2128  mach_ = &mach;
2129  if (AA) {
2130  for (unsigned int i = 0; i < aliasAnalyzers_.size(); i++) {
2131  LLVMAliasAnalyzer* llvmaa =
2132  dynamic_cast<LLVMAliasAnalyzer*>(aliasAnalyzers_[i]);
2133  if (llvmaa != NULL) {
2134  llvmaa->setLLVMAA(AA);
2135  }
2136  }
2137  }
2138 
2139  cfg_ = &cfg;
2140 
2141  // @TODO: when CFG subgraphs are in use, 2nd param not always true
2143  allParamRegs_, cfg.name(), antidependenceLevel, NULL, true,
2144  false);
2145  try {
2146  // this is just for old frontend code.
2147  if (um != NULL) {
2149  } else {
2151  }
2152 
2153  currentDDG_ = ddg;
2154 
2155  // do the first phase (register dependencies and operation edges)
2157 
2158  // then do the second phase - mem and fu deps.
2159  if (createMemAndFUDeps) {
2161  }
2162 
2163  // search when registers are used for last time.
2164  // this live range information is used by register renamer and
2165  // threading.
2166  if (createDeathInformation) {
2168  }
2169 
2170  // clear bookkeeping which is not needed anymore.
2172  } catch (const Exception& e) {
2174  << e.fileName() << ": " << e.lineNum() << ": " << e.errorMessageStack()
2175  << std::endl;
2176  delete ddg;
2177  throw;
2178  } catch (...) {
2179  delete ddg;
2180  throw;
2181  }
2182  ddg->setMachine(mach);
2183  return ddg;
2184 }

References aliasAnalyzers_, allParamRegs_, cfg_, clearUnneededBookkeeping(), createMemAndFUstateDeps(), createRegisterDeps(), currentDDG_, Exception::errorMessageStack(), Exception::fileName(), findStaticRegisters(), Exception::lineNum(), Application::logStream(), mach_, BoostGraph< GraphNode, GraphEdge >::name(), searchRegisterDeaths(), LLVMAliasAnalyzer::setLLVMAA(), DataDependenceGraph::setMachine(), and specialRegisters_.

Referenced by BUMoveNodeSelector::BUMoveNodeSelector(), llvm::LLVMTCEIRBuilder::compileOptimized(), BasicBlockPass::createDDGFromBB(), BBSchedulerController::createDDGFromBB(), CriticalPathBBMoveNodeSelector::CriticalPathBBMoveNodeSelector(), PreOptimizer::handleControlFlowGraph(), BBSchedulerController::handleProcedure(), and ProgramGraph::ProgramGraph().

Here is the call graph for this function:

◆ build() [2/2]

DataDependenceGraph * DataDependenceGraphBuilder::build ( TTAProgram::BasicBlock bb,
DataDependenceGraph::AntidependenceLevel  registerAntidependenceLevel,
const TTAMachine::Machine mach,
const TCEString ddgName = "small bb",
const UniversalMachine um = NULL,
bool  createMemAndFUDeps = true,
llvm::AliasAnalysis AA = NULL 
)
virtual

Creates new Data Dependence Graph for the given basic block.

Client has to delete the graph when it is not anymore used.

Parameters
bbBasicBlockNode whose data dependence graph to build.
registerAntidependenceLevelwhich reg antidependencies to create
createMemAndFUDepswhether to create also memory and fu state(side effect) dependencies or only register deps.
Returns
new DataDependence Graph.

Definition at line 456 of file DataDependenceGraphBuilder.cc.

463  {
464 
465  mach_ = &mach;
466  if (AA) {
467  for (unsigned int i = 0; i < aliasAnalyzers_.size(); i++) {
468  LLVMAliasAnalyzer* llvmaa =
469  dynamic_cast<LLVMAliasAnalyzer*>(aliasAnalyzers_[i]);
470  if (llvmaa != NULL) {
471  llvmaa->setLLVMAA(AA);
472  }
473  }
474  }
475  if (bb.liveRangeData_ == NULL) {
476  bb.liveRangeData_ = new LiveRangeData;
477  }
478 
479  currentBB_ = new BasicBlockNode(bb);
481  allParamRegs_, ddgName, registerAntidependenceLevel, currentBB_,
482  false,true);
483  // GRR, start and end addresses are lost..
484 
485  currentData_ = new BBData(*currentBB_);
486 
487  if (um != NULL) {
489  } else {
491  }
492  try {
493  // first phase. registers , ops and PO's.
496  if (createMemAndFUDeps) {
497  //second phase. mem and fu state deps
500  }
501  } catch (Exception&) {
502  delete currentDDG_; currentDDG_ = NULL;
503  delete currentData_; currentData_ = NULL;
504  delete currentBB_; currentBB_ = NULL;
505  throw;
506  }
507 
508  clearUnneededBookkeeping(bb, false);
509 
510  delete currentData_;
511  currentData_ = NULL;
512  currentDDG_->setMachine(mach);
513  return currentDDG_;
514 }

References aliasAnalyzers_, allParamRegs_, clearUnneededBookkeeping(), constructIndividualBB(), currentBB_, currentData_, currentDDG_, findStaticRegisters(), TTAProgram::BasicBlock::liveRangeData_, mach_, MEMORY_AND_SIDE_EFFECTS, REGISTERS_AND_PROGRAM_OPERATIONS, LLVMAliasAnalyzer::setLLVMAA(), DataDependenceGraph::setMachine(), and specialRegisters_.

Here is the call graph for this function:

◆ changeState()

void DataDependenceGraphBuilder::changeState ( BBData bbd,
BBState  newState,
bool  priorize = false 
)
protected

Changes state of a basic block in processing. Move BBData into a diffefent list and changes the state data in BBData.

Parameters
bbdBBData of basic block whose state is being changed
newStatethe new state of the basic block.

Definition at line 2217 of file DataDependenceGraphBuilder.cc.

2218  {
2219 
2220  BBState oldState = bbd.state_;
2221  if (newState != oldState) {
2223  bbd.state_ = newState;
2224  if (priorize) {
2225  blocksByState_[newState].push_front(&bbd);
2226  } else {
2227  blocksByState_[newState].push_back(&bbd);
2228  }
2229  }
2230 }

References blocksByState_, ContainerTools::removeValueIfExists(), and DataDependenceGraphBuilder::BBData::state_.

Referenced by createMemAndFUstateDeps(), createRegisterDeps(), iterateBBs(), iterateRegisterDeaths(), queueFirstBB(), searchRegisterDeaths(), setSucceedingPredepsForBB(), and updatePreceedingRegistersUsedAfter().

Here is the call graph for this function:

◆ checkAndCreateMemAntideps()

void DataDependenceGraphBuilder::checkAndCreateMemAntideps ( MoveNodeUse mnd,
std::set< MoveNodeUse > &  prevNodes,
DataDependenceEdge::DependenceType  depType,
bool  traceable 
)
protected

Creates memory dependencies from set of nodes to given nodes.

Does not create if gaurds of aliasing dictate edge not needed. If both guard and aliasing indicate fully transitive case for some prev nodes, then remove these previous nodes from the bookkeeping.

Definition at line 1718 of file DataDependenceGraphBuilder.cc.

1721  {
1722  // create WaW to another in own bb
1723  for (MoveNodeUseSet::iterator iter =
1724  prevNodes.begin(); iter != prevNodes.end();) {
1725  if ((checkAndCreateMemDep(*iter, mnd, depType) || !traceable) &&
1726  (mnd.mn()->move().isUnconditional() ||
1727  currentDDG_->sameGuards(*(iter->mn()), *(mnd.mn())))) {
1728  // remove current element and update iterator to next.
1729  prevNodes.erase(iter++);
1730  } else { // just take next from the set
1731  iter++;
1732  }
1733  }
1734 }

References checkAndCreateMemDep(), currentDDG_, TTAProgram::Move::isUnconditional(), MoveNodeUse::mn(), MoveNode::move(), and DataDependenceGraph::sameGuards().

Referenced by processMemWrite().

Here is the call graph for this function:

◆ checkAndCreateMemDep()

bool DataDependenceGraphBuilder::checkAndCreateMemDep ( MoveNodeUse  prev,
MoveNodeUse  mnd,
DataDependenceEdge::DependenceType  depType 
)
protected

Compares a memory op against one previous memory ops and creates dependence if may alias.

Parameters
prevPrevious Memory write movenode
mnCurrent memory write movenode
depTypedependence type which to create.
Returns
true if true alias.

Definition at line 1841 of file DataDependenceGraphBuilder.cc.

1843  {
1844 
1845  // cannot be dep if opposite guards.
1846  if (currentDDG_->exclusingGuards(*(prev.mn()), *(mnd.mn()))) {
1847  return false;
1848  }
1849 
1852 
1853  // only for true stores and loads; we cannot analyze aliasing
1854  // of pseudo dependencies caused by call/return.
1855  if (!prev.pseudo() && !mnd.pseudo()) {
1856  ProgramOperation& currPop = mnd.mn()->destinationOperation();
1857  ProgramOperation& prevPop = prev.mn()->destinationOperation();
1858 
1859  const llvm::MachineInstr* instr1 = currPop.machineInstr();
1860  const llvm::MachineInstr* instr2 = prevPop.machineInstr();
1861 
1862  // The LLVM MachineInstructions are not connected to
1863  // all memory operands, at least not to those in inline
1864  // assembly blocks (from custom operation calls).
1865  if (instr1 != NULL && instr2 != NULL) {
1866  llvm::MachineInstr::mmo_iterator begin1 =
1867  instr1->memoperands_begin();
1868  // Machine instruction could in theory have several memory operands.
1869  // In practice it is usually just one.
1870  while (begin1 != instr1->memoperands_end()) {
1871  llvm::MachineInstr::mmo_iterator begin2 =
1872  instr2->memoperands_begin();
1873 
1874  while (begin2 != instr2->memoperands_end()) {
1875  // Force program ordering between volatile mem accesses.
1876  if ((*begin1)->isVolatile() && (*begin2)->isVolatile()) {
1877 #if 0
1878  Application::logStream() << "MemDep >> volatile \n";
1879  PRINT_VAR(currPop.toString());
1880  PRINT_VAR(prevPop.toString());
1881  (*begin1)->getValue()->dump();
1882  (*begin2)->getValue()->dump();
1883 #endif
1884  aliasResult = MemoryAliasAnalyzer::ALIAS_PARTIAL;
1885  }
1886  begin2++;
1887  }
1888  begin1++;
1889  }
1890  }
1891  if (aliasResult == MemoryAliasAnalyzer::ALIAS_UNKNOWN)
1892  aliasResult = analyzeMemoryAlias(prevPop, currPop, prev.bbRelation());
1893  }
1894 
1895  if (aliasResult != MemoryAliasAnalyzer::ALIAS_FALSE) {
1896  // if not alias false , have to create mem edge.
1897  bool trueAlias = (aliasResult == MemoryAliasAnalyzer::ALIAS_TRUE);
1898  ProgramOperation& prevPo = prev.mn()->destinationOperation();
1899  for (int i = 0; i < prevPo.inputMoveCount(); i++) {
1900  if (prev.loop() || &prevPo.inputMove(i) != mnd.mn()) {
1901  // if operations are always assigned to differnt FU,
1902  // then skip creating memroy dependency edge
1903  if (isAlwaysDifferentFU(prev.mn(), mnd.mn())) {
1904  continue;
1905  }
1906  DataDependenceEdge* dde2 =
1907  new DataDependenceEdge(
1908  DataDependenceEdge::EDGE_MEMORY, depType, false,
1909  trueAlias, prev.pseudo(), mnd.pseudo(),
1910  static_cast<int>(prev.loop()));
1912  prevPo.inputMove(i), *mnd.mn(), dde2);
1913  }
1914  }
1915  return trueAlias;
1916  }
1917  return false;
1918 }

References MemoryAliasAnalyzer::ALIAS_FALSE, MemoryAliasAnalyzer::ALIAS_PARTIAL, MemoryAliasAnalyzer::ALIAS_TRUE, MemoryAliasAnalyzer::ALIAS_UNKNOWN, analyzeMemoryAlias(), MoveNodeUse::bbRelation(), DataDependenceGraph::connectOrDeleteEdge(), currentDDG_, MoveNode::destinationOperation(), DataDependenceEdge::EDGE_MEMORY, DataDependenceGraph::exclusingGuards(), ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), isAlwaysDifferentFU(), Application::logStream(), MoveNodeUse::loop(), ProgramOperation::machineInstr(), MoveNodeUse::mn(), PRINT_VAR, MoveNodeUse::pseudo(), and ProgramOperation::toString().

Referenced by checkAndCreateMemAntideps(), processMemUse(), updateMemUse(), and updateMemWrite().

Here is the call graph for this function:

◆ clearUnneededBookkeeping() [1/2]

void DataDependenceGraphBuilder::clearUnneededBookkeeping ( )
protected

Clears bookkeeping which is only needed during ddg construction.

Definition at line 2251 of file DataDependenceGraphBuilder.cc.

2251  {
2252 
2253  for (int i = 0; i < cfg_->nodeCount();i++) {
2254  BasicBlockNode& bbn = cfg_->node(i);
2255  if (bbn.isNormalBB()) {
2256  BasicBlock& bb = bbn.basicBlock();
2257  clearUnneededBookkeeping(bb, true);
2258  }
2259  }
2260 }

References BasicBlockNode::basicBlock(), cfg_, BasicBlockNode::isNormalBB(), BoostGraph< GraphNode, GraphEdge >::node(), and BoostGraph< GraphNode, GraphEdge >::nodeCount().

Referenced by build().

Here is the call graph for this function:

◆ clearUnneededBookkeeping() [2/2]

void DataDependenceGraphBuilder::clearUnneededBookkeeping ( TTAProgram::BasicBlock bb,
bool  interBBInformationNeeded = true 
)
protected

Clears bookkeeping which is only needed during ddg construction.

Parameters
BBcontaining basic blocks which contain the bookkeeping.
interBBInformationneeded whether information about inter-bb- dependencies need to be left intact.

Definition at line 899 of file DataDependenceGraphBuilder.cc.

900  {
901 
902  if (!interBBInformationNeeded) {
903  //used by regcopyadder.
904  bb.liveRangeData_->regFirstDefines_.clear();
905  bb.liveRangeData_->regLastUses_.clear();
906 
907  // used by both
908  bb.liveRangeData_->regDefines_.clear();
909 
910  // these are neede for live range things
911  bb.liveRangeData_->regDefReaches_.clear();
913  bb.liveRangeData_->regFirstUses_.clear();
914  }
915  bb.liveRangeData_->regUseReaches_.clear();
916  bb.liveRangeData_->regLastKills_.clear();
917 
918  bb.liveRangeData_->regDefAfter_.clear();
919  bb.liveRangeData_->regUseAfter_.clear();
920 
921  bb.liveRangeData_->memDefines_.clear();
922  bb.liveRangeData_->memLastUses_.clear();
923 
924  bb.liveRangeData_->memFirstUses_.clear();
925  bb.liveRangeData_->memFirstDefines_.clear();
926 
927  bb.liveRangeData_->memDefReaches_.clear();
928  bb.liveRangeData_->memUseReaches_.clear();
929 
930  bb.liveRangeData_->fuDepReaches_.clear();
931  bb.liveRangeData_->fuDeps_.clear();
932  bb.liveRangeData_->fuDepAfter_.clear();
933 
935 }

References LiveRangeData::fuDepAfter_, LiveRangeData::fuDepReaches_, LiveRangeData::fuDeps_, TTAProgram::BasicBlock::liveRangeData_, LiveRangeData::memDefines_, LiveRangeData::memDefReaches_, LiveRangeData::memFirstDefines_, LiveRangeData::memFirstUses_, LiveRangeData::memLastUses_, LiveRangeData::memUseReaches_, LiveRangeData::regDefAfter_, LiveRangeData::regDefines_, LiveRangeData::regDefReaches_, LiveRangeData::regFirstDefines_, LiveRangeData::regFirstUses_, LiveRangeData::registersUsedAfter_, LiveRangeData::registersUsedInOrAfter_, LiveRangeData::regLastKills_, LiveRangeData::regLastUses_, LiveRangeData::regUseAfter_, and LiveRangeData::regUseReaches_.

◆ constructBB()

void DataDependenceGraphBuilder::constructBB ( BasicBlockNodeSet inputBlocks)
protected

◆ constructIndividualBB() [1/2]

void DataDependenceGraphBuilder::constructIndividualBB ( BBData bbd,
ConstructionPhase  phase 
)
protected

Constructs a Data Dependence Graph for a single basic block.

Goes thru all moves in the basic block and analyzes their dependencies, creates their ProgramOperations, MoveNodes and Edges, and adds the nodes and edges to the graph. Also used inside implementation of multi-BB-DDG-code. BB being analyzed has to be already set in member variable currentBB_, and the graph created and set into member variable currentBB_.

Parameters
bbdbasic block to constructs.
phasewhether to handle register& operation deps or memory and side-effect dependencies.

Definition at line 531 of file DataDependenceGraphBuilder.cc.

532  {
533 
534  currentData_ = &bbd;
535  currentBB_ = bbd.bblock_;
536 
537  // Parallel inline asm block are already marked as scheduled
538  // TODO: should BBN have isInlineAsm() method?
539  if (currentBB_->isScheduled()) {
541  } else {
542  constructIndividualBB(phase);
543  }
544 }

References DataDependenceGraphBuilder::BBData::bblock_, constructIndividualBB(), constructIndividualFromInlineAsmBB(), currentBB_, currentData_, and BasicBlockNode::isScheduled().

Here is the call graph for this function:

◆ constructIndividualBB() [2/2]

void DataDependenceGraphBuilder::constructIndividualBB ( ConstructionPhase  phase)
protected

Constructs a Data Dependence Graph for a single basic block.

Goes thru all moves in the basic block and analyzes their dependencies, creates their ProgramOperations, MoveNodes and Edges, and adds the nodes and edges to the graph. Also used inside implementation of multi-BB-DDG-code. BB being analyzed has to be already set in member variable currentBB_, and the graph created and set into member variable currentBB_.

Parameters
phasewhether to handle register& operation deps or memory and side-effect dependencies.

Definition at line 560 of file DataDependenceGraphBuilder.cc.

561  {
562 
563  for (int ia = 0; ia < currentBB_->basicBlock().instructionCount(); ia++) {
565 
566  for (int i = 0; i < ins.moveCount(); i++) {
567  auto movePtr = ins.movePtr(i);
568  Move& move = *movePtr;
569 
570  MoveNode* moveNode = NULL;
571 
572  // if phase is 0, create the movenode, and handle guard.
573  if (phase == REGISTERS_AND_PROGRAM_OPERATIONS) {
574  /* In case using the LLVMTCEIRBuilder, the POs have been built already
575  and set to corresponding TerminalFUPorts. Use those MoveNodes and
576  ProgramOperations instead of creating new ones here. NOTE: the
577  ownership of the MoveNodes is transferred to the DDG.
578  */
579  if (move.destination().isFUPort() &&
580  dynamic_cast<TerminalFUPort&>(move.destination()).
581  hasProgramOperation()) {
582  ProgramOperationPtr po =
583  dynamic_cast<TerminalFUPort&>(move.destination()).
584  programOperation();
585  if (po->hasMoveNodeForMove(move)) {
586  moveNode = &po->moveNode(move);
587  } else {
588  // the po might be corrupted and point to an old POM's Moves
589  moveNode = new MoveNode(movePtr);
590  }
591  } else if (move.source().isFUPort() &&
592  dynamic_cast<TerminalFUPort&>(move.source()).
593  hasProgramOperation()) {
594  ProgramOperationPtr po =
595  dynamic_cast<TerminalFUPort&>(move.source()).
596  programOperation();
597  if (po->hasMoveNodeForMove(move)) {
598  moveNode = &po->moveNode(move);
599  } else {
600  // the po might be corrupted and point to an old POM's Moves
601  moveNode = new MoveNode(movePtr);
602  }
603  } else {
604  moveNode = new MoveNode(movePtr);
605  }
606  currentDDG_->addNode(*moveNode, *currentBB_);
607 
608  if (!move.isUnconditional()) {
609  processGuard(*moveNode);
610  }
611 
612  processSource(*moveNode);
613 
614  } else {
615  // on phase 2, just find the already created movenode.
616  moveNode = &currentDDG_->nodeOfMove(move);
617  }
618 
619  // destinaition need to be processed in both phases 0 and 1.
620  processDestination(*moveNode, phase);
621  }
622  }
623 
624  // these are needed no more.
626 
627  // Checks if we have some unready program operations at the end
628  // of a basic block.
629  if (currentData_->destPending_ != NULL ||
630  currentData_->readPending_ != NULL) {
631 
632  TCEString msg = TCEString("Basic block ")
634  + TCEString(" - ")
636  + TCEString(", size : ")
639  + TCEString(" handled but we have unready PO at: ")
640  + currentDDG_->name()
641  + TCEString(", probably an operation without result move?");
642 
643  if (currentData_->readPending_ != NULL) {
644  msg += "\n\tmissing read: " +
645  TCEString(currentData_->readPending_->operation().name());
646  }
647 
648  if (currentData_->destPending_ != NULL) {
649  msg += "\n\tmissing dest: " +
650  TCEString(currentData_->destPending_->operation().name());
651  }
652 
653  if (cfg_ != NULL) {
654  cfg_->writeToDotFile("constructBBbroken_cfg.dot");
655  }
656 
657  throw IllegalProgram(__FILE__,__LINE__,__func__, msg);
658  }
659 }

References __func__, DataDependenceGraph::addNode(), BasicBlockNode::basicBlock(), cfg_, currentBB_, currentData_, currentDDG_, TTAProgram::Move::destination(), DataDependenceGraphBuilder::BBData::destPending_, TTAProgram::CodeSnippet::instructionAtIndex(), TTAProgram::CodeSnippet::instructionCount(), TTAProgram::Terminal::isFUPort(), TTAProgram::Move::isUnconditional(), TTAProgram::BasicBlock::liveRangeData_, TTAProgram::Instruction::moveCount(), TTAProgram::Instruction::movePtr(), BoostGraph< GraphNode, GraphEdge >::name(), DataDependenceGraph::nodeOfMove(), BasicBlockNode::originalEndAddress(), BasicBlockNode::originalStartAddress(), LiveRangeData::potentialRegKills_, processDestination(), processGuard(), processSource(), DataDependenceGraphBuilder::BBData::readPending_, REGISTERS_AND_PROGRAM_OPERATIONS, TTAProgram::Move::source(), Conversion::toString(), and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by build(), constructIndividualBB(), and iterateBBs().

Here is the call graph for this function:

◆ constructIndividualFromInlineAsmBB()

void DataDependenceGraphBuilder::constructIndividualFromInlineAsmBB ( ConstructionPhase  phase)
protected

Same as constructIndividualBB() but for already fully scheduled and inline asm BB.

@Note: currently, this does not really construct DDG - just creates dummy MoveNodes.

Definition at line 669 of file DataDependenceGraphBuilder.cc.

670  {
671 
672  if (phase != REGISTERS_AND_PROGRAM_OPERATIONS) {
673  return;
674  }
675  auto& bb = currentBB_->basicBlock();
677  for (int ia = 0; ia < bb.instructionCount(); ia++) {
678  Instruction& ins = bb.instructionAtIndex(ia);
679  for (int i = 0; i < ins.moveCount(); i++) {
680  MoveNode* moveNode = new MoveNode(ins.movePtr(i));
681  currentDDG_->addNode(*moveNode, *currentBB_);
682  }
683  }
684 
685  // Process live range with dummy move nodes.
686  assert(bb.liveRangeData_);
687  LiveRangeData& liveRangeData = *bb.liveRangeData_;
688  std::set<TCEString> actualRegUses;
689  std::set<TCEString> actualRegDefs;
690  for (int i = 0; i < bb.instructionCount(); i++) {
691  auto& ins = bb.instructionAtIndex(i);
692  for (int m = 0; m < ins.moveCount(); m++) {
693  auto& move = ins.move(m);
694 
695  auto rdReg = move.source().isGPR() ? move.source().toString()
696  : TCEString("");
697  if (!rdReg.empty()) actualRegUses.insert(rdReg);
698 
699  if (move.isConditional()) {
700  const Guard& grd = move.guard().guard();
701  const RegisterGuard* grdReg =
702  dynamic_cast<const RegisterGuard*>(&grd);
703  if (grdReg) {
704  TCEString regName = grdReg->registerFile()->name() + '.' +
706  actualRegUses.insert(regName);
707  }
708  }
709 
710  auto wrReg = move.destination().isGPR()
711  ? move.destination().toString()
712  : TCEString("");
713  if (!wrReg.empty()) actualRegDefs.insert(wrReg);
714  }
715  }
716 
717  auto& iaRegUses = liveRangeData.inlineAsmRegUses_;
718  auto effectiveRegUses = SetTools::intersection(iaRegUses, actualRegUses);
719  for (auto reg : effectiveRegUses) {
720  MoveNode* moveNode = new MoveNode();
721  currentDDG_->addNode(*moveNode, *currentBB_);
722  liveRangeData.regFirstUses_[reg].insert(*moveNode);
723  currentDDG_->updateRegUse(*moveNode, reg, bb);
724  }
725 
726  auto& iaRegDefs = liveRangeData.inlineAsmRegDefs_;
727  auto effectiveRegDefs = SetTools::intersection(iaRegDefs, actualRegDefs);
728  for (auto reg : effectiveRegDefs) {
729  MoveNode* moveNode = new MoveNode();
730  currentDDG_->addNode(*moveNode, *currentBB_);
731  liveRangeData.regDefines_[reg].insert(*moveNode);
732  MoveNodeUse mnd(*moveNode);
733  liveRangeData.regKills_[reg] = std::make_pair(mnd, mnd);
734  }
735 
736  for (auto& reg : liveRangeData.inlineAsmClobbers_) {
737  MoveNode* moveNode = new MoveNode();
738  currentDDG_->addNode(*moveNode, *currentBB_);
739  liveRangeData.regDefines_[reg].insert(*moveNode);
740  MoveNodeUse mnd(*moveNode);
741  liveRangeData.regKills_[reg] = std::make_pair(mnd, mnd);
742  }
743 
744  // Not needed anymore.
745  liveRangeData.inlineAsmRegUses_.clear();
746  liveRangeData.inlineAsmRegDefs_.clear();
747  liveRangeData.inlineAsmClobbers_.clear();
748 }

References DataDependenceGraph::addNode(), assert, BasicBlockNode::basicBlock(), currentBB_, currentDDG_, LiveRangeData::inlineAsmClobbers_, LiveRangeData::inlineAsmRegDefs_, LiveRangeData::inlineAsmRegUses_, SetTools::intersection(), BasicBlockNode::isScheduled(), TTAProgram::Instruction::moveCount(), TTAProgram::Instruction::movePtr(), TTAMachine::Component::name(), LiveRangeData::regDefines_, LiveRangeData::regFirstUses_, TTAMachine::RegisterGuard::registerFile(), TTAMachine::RegisterGuard::registerIndex(), REGISTERS_AND_PROGRAM_OPERATIONS, LiveRangeData::regKills_, Conversion::toString(), and DataDependenceGraph::updateRegUse().

Referenced by constructIndividualBB().

Here is the call graph for this function:

◆ createMemAndFUstateDeps()

void DataDependenceGraphBuilder::createMemAndFUstateDeps ( )
protected

Does the second phase of ddg construction.

handles mem deps and fu state deps.

Definition at line 2312 of file DataDependenceGraphBuilder.cc.

2312  {
2313 
2314  // initializes states of all BB's to unreached.
2316 
2317  // queues first bb for processing
2318  queueFirstBB();
2319 
2320  // then iterates over all basic blocks.
2322 
2323  // all should be constructed, but if there are unreachable BB's
2324  // we might want to handle those also
2325  while (!blocksByState_[BB_UNREACHED].empty()) {
2328  }
2329  // free bb data
2331 }

References BB_QUEUED, BB_UNREACHED, bbData_, blocksByState_, changeState(), AssocTools::deleteAllValues(), initializeBBStates(), iterateBBs(), MEMORY_AND_SIDE_EFFECTS, and queueFirstBB().

Referenced by build().

Here is the call graph for this function:

◆ createOperationEdges()

void DataDependenceGraphBuilder::createOperationEdges ( ProgramOperationPtr  po)
protected

Creates operand edges between input and output moves of a programoperation.

Parameters
poProgramOperation whose egdes we are creating.

Definition at line 1141 of file DataDependenceGraphBuilder.cc.

1142  {
1143 
1144  const Operation& op = po->operation();
1145 
1146  // loop over all input nodes
1147  for (int i = 0; i < po->inputMoveCount(); i++) {
1148  MoveNode& inputNode = po->inputMove(i);
1149  // loop over all output nodes.
1150  for (int j = 0; j < po->outputMoveCount(); j++) {
1151  MoveNode& outputNode = po->outputMove(j);
1152 
1153  // and create operation edges
1154  // from all input nodes to all
1155  // output nodes.
1156  DataDependenceEdge* dde =
1157  new DataDependenceEdge(
1160  op.name());
1161 
1163  inputNode, outputNode, dde);
1164  }
1165  }
1166 }

References DataDependenceGraph::connectOrDeleteEdge(), currentDDG_, DataDependenceEdge::DEP_UNKNOWN, DataDependenceEdge::EDGE_OPERATION, and Operation::name().

Referenced by LLVMTCEDataDependenceGraphBuilder::buildLocalDDG(), and processResultRead().

Here is the call graph for this function:

◆ createRegisterAntideps()

void DataDependenceGraphBuilder::createRegisterAntideps ( const TCEString reg,
MoveNodeUse mnd,
MoveNodeUseSet predecessorNodes,
DataDependenceEdge::DependenceType  depType,
bool  guardedKillFound 
)
protected

Creates register antidependencies from set of movenodeuses to one movenode.

Parameters
mndMovenode which to creat those dependencies
predecessorNodesNodes where to create dependencies from
depTypewhether to create WAR or WAW antidependencies
guardedKillFoundif there is a write with same guard to the reg.

Definition at line 1303 of file DataDependenceGraphBuilder.cc.

1307  {
1308 
1309  // create dep to another in own bb
1310  for (std::set<MoveNodeUse>::iterator i = predecessorNodes.begin();
1311  i != predecessorNodes.end();) {
1312 
1313  if (depType == DataDependenceEdge::DEP_WAW) {
1314  // If we do not have a guarded kill, draw edges from all defines.
1315  // If we have a guarded kill, only draw edges from
1316  // unconditional moves, as the guarded kill overshadows the
1317  // inconditional writes.
1318  if (guardedKillFound && i->mn()->move().isUnconditional()) {
1319  i++;
1320  continue;
1321  }
1322  } else {
1323  assert(depType == DataDependenceEdge::DEP_WAR);
1324  // skip if war to itself, ie move foo.1 -> foo.1
1325  if (i->mn() == mnd.mn()) {
1326  i++;
1327  continue;
1328  }
1329  }
1330 
1331  // Do not create antideps if have excluding guards
1332  // But always create antidep if this writes to a reg which is
1333  // used as guard for the previous move.
1334  if (!currentDDG_->exclusingGuards(*(i->mn()), *(mnd.mn())) ||
1335  i->guard()) {
1336 
1337  // create dependency edge
1338  DataDependenceEdge* dde =
1339  new DataDependenceEdge(
1342  depType, reg, i->guard(), false,
1343  i->pseudo(), mnd.pseudo(), i->loop());
1344 
1345  // and connect
1346  currentDDG_->connectOrDeleteEdge(*i->mn(), *mnd.mn(), dde);
1347 
1348  // if have same guards, remove the old from bookkeeping
1349  // this completely overshadows it
1350  if (currentDDG_->sameGuards(*(i->mn()), *(mnd.mn()))) {
1351  predecessorNodes.erase(i++);
1352  continue;
1353  }
1354  }
1355  i++;
1356  }
1357 }

References assert, DataDependenceGraph::connectOrDeleteEdge(), currentDDG_, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, DataDependenceGraph::exclusingGuards(), MoveNodeUse::mn(), MoveNodeUse::pseudo(), MoveNodeUse::ra(), and DataDependenceGraph::sameGuards().

Referenced by processRegWrite().

Here is the call graph for this function:

◆ createRegisterDeps()

void DataDependenceGraphBuilder::createRegisterDeps ( )
protected

Does the first phase of ddg construction. handles register deps.

Parameters
cfgcontrol flow graph containing the code.

Definition at line 2268 of file DataDependenceGraphBuilder.cc.

2268  {
2269 
2270  // initializes states of all BB's to unreached.
2272 
2273  // queues first bb for processing
2274  BasicBlockNode* firstBB = queueFirstBB();
2275 
2276  // currentBB need to be set for entry node processing
2277  currentBB_ = firstBB;
2278 
2279  // set entry deps. ( procedure parameter edges )
2280  MoveNode* entryNode = new MoveNode();
2281  currentDDG_->addNode(*entryNode, cfg_->entryNode());
2282 
2283  processEntryNode(*entryNode);
2284 
2285  // iterate over BB's. Loop as long as there are queued BB's.
2286 
2288 
2289  // all should be constructed, but if there are unreachable BB's
2290  // we handle those also
2291  while (!blocksByState_[BB_UNREACHED].empty()) {
2293  Application::logStream() << "Warning: Unreachable Basic Block!"
2294  << std::endl;
2295  Application::logStream() << "In procedure: " << cfg_->name() <<
2296  std::endl;
2297 // cfg.writeToDotFile("unreachable_bb.dot");
2298  }
2301  }
2302  // free bb data
2304 }

References DataDependenceGraph::addNode(), BB_QUEUED, BB_UNREACHED, bbData_, blocksByState_, cfg_, changeState(), currentBB_, currentDDG_, AssocTools::deleteAllValues(), ControlFlowGraph::entryNode(), initializeBBStates(), iterateBBs(), Application::logStream(), BoostGraph< GraphNode, GraphEdge >::name(), processEntryNode(), queueFirstBB(), REGISTERS_AND_PROGRAM_OPERATIONS, Application::VERBOSE_LEVEL_DEFAULT, and Application::verboseLevel().

Referenced by build().

Here is the call graph for this function:

◆ createSideEffectEdges()

void DataDependenceGraphBuilder::createSideEffectEdges ( MoveNodeUseSet prevMoves,
const MoveNode mn,
Operation dop 
)
protected

Definition at line 1646 of file DataDependenceGraphBuilder.cc.

1647  {
1648 
1649  OperationPool pool;
1650  if (pool.sharesState(dop) || dop.hasSideEffects()) {
1651  for (MoveNodeUseSet::iterator i = prevMoves.begin();
1652  i != prevMoves.end(); i++) {
1653  const Operation& o = i->mn()->destinationOperation().operation();
1654 
1655  // mem writes are handled by memory deps so exclude here
1656  if ((&dop == &o && o.hasSideEffects()) ||
1657  dop.dependsOn(o) || o.dependsOn(dop)) {
1658  // if operations are always assigned to differnt FU,
1659  // skip creating dependency edge
1660  if (isAlwaysDifferentFU(&mn, i->mn())) continue;
1661 
1662  if (!currentDDG_->exclusingGuards(*(i->mn()), mn)) {
1663  DataDependenceEdge* dde =
1664  new DataDependenceEdge(
1666  DataDependenceEdge::DEP_UNKNOWN, false,false,false,
1667  false, static_cast<int>(i->loop()));
1669  *(i->mn()), mn, dde);
1670  }
1671  }
1672  }
1673  }
1674 }

References DataDependenceGraph::connectOrDeleteEdge(), currentDDG_, DataDependenceEdge::DEP_UNKNOWN, Operation::dependsOn(), DataDependenceEdge::EDGE_FUSTATE, DataDependenceGraph::exclusingGuards(), Operation::hasSideEffects(), isAlwaysDifferentFU(), and OperationPool::sharesState().

Referenced by createTriggerDependencies(), and updateBB().

Here is the call graph for this function:

◆ createTriggerDependencies()

void DataDependenceGraphBuilder::createTriggerDependencies ( class MoveNode moveNode,
class Operation dop 
)
protected

Analyzes operation of a trigger write.

If memory read, calls processMemRead to manage memory read dependencies. Manages FU State dependencies between operations.

Parameters
moveNodemnData related to a move which triggers an operation
dopOperation being triggered

Definition at line 1596 of file DataDependenceGraphBuilder.cc.

1597  {
1598 
1599  if (dop.readsMemory()) {
1600  processMemUse(MoveNodeUse(moveNode));
1601  } //TODO: avoid drawing antidep to itself
1602 
1603  if (dop.writesMemory()) {
1604  processMemWrite(MoveNodeUse(moveNode));
1605  }
1606 
1609  currentBB_->basicBlock().liveRangeData_->fuDepReaches_, moveNode, dop);
1610 
1611  OperationPool pool;
1612  if (dop.hasSideEffects() || pool.sharesState(dop)) {
1613 
1614  // remove old same op from bookkeeping.
1615  // this should prevent exponential explosion of edge count.
1616  if (dop.hasSideEffects() && moveNode.move().isUnconditional()) {
1617  for (MoveNodeUseSet::iterator iter =
1619  iter != currentBB_->basicBlock().liveRangeData_->fuDeps_.end(); iter++) {
1620 
1621  const Operation& o =
1622  iter->mn()->destinationOperation().operation();
1623  if (&o == &dop) {
1624  currentBB_->basicBlock().liveRangeData_->fuDeps_.erase(iter);
1625  break;
1626  }
1627  }
1628  }
1629  // add the new one to bookkeeping
1630  currentBB_->basicBlock().liveRangeData_->fuDeps_.insert(MoveNodeUse(moveNode));
1631  }
1632 }

References BasicBlockNode::basicBlock(), createSideEffectEdges(), currentBB_, LiveRangeData::fuDepReaches_, LiveRangeData::fuDeps_, Operation::hasSideEffects(), TTAProgram::Move::isUnconditional(), TTAProgram::BasicBlock::liveRangeData_, MoveNode::move(), processMemUse(), processMemWrite(), Operation::readsMemory(), OperationPool::sharesState(), and Operation::writesMemory().

Referenced by processTriggerMemoryAndFUStates().

Here is the call graph for this function:

◆ earlierWritesWithSameGuard()

std::set< MoveNodeUse > DataDependenceGraphBuilder::earlierWritesWithSameGuard ( MoveNodeUse mnd,
std::set< MoveNodeUse > &  defines 
)
protected

Definition at line 1200 of file DataDependenceGraphBuilder.cc.

1201  {
1202 
1203  std::set<MoveNodeUse> results;
1204  // first just check if there is earlier write to this reg with same guard..
1205  for (std::set<MoveNodeUse>::iterator i = defines.begin();
1206  i != defines.end(); i++) {
1207  // if earlier write to this reg with same guard..
1208  if (!mnd.guard() &&
1209  !i->mn()->move().isUnconditional() &&
1210  currentDDG_->sameGuards(*(i->mn()), *(mnd.mn()))) {
1211  results.insert(*i);
1212  }
1213  }
1214  return results;
1215 }

References currentDDG_, MoveNodeUse::guard(), MoveNodeUse::mn(), and DataDependenceGraph::sameGuards().

Referenced by processRegUse().

Here is the call graph for this function:

◆ findStaticRegisters() [1/4]

void DataDependenceGraphBuilder::findStaticRegisters ( const UniversalMachine um,
std::map< int, TCEString > &  registers 
)
protected

Initializes the static register table from register from UniversalMachine.

Needed for analysis of data dependencies of parameter registers, SP, RV etc.

Parameters
umUniversalMachine
registersmap where to store those registers.

Definition at line 421 of file DataDependenceGraphBuilder.cc.

422  {
424 
425  for (int i = 0; i < 6; i++) {
426  TerminalRegister tr(*rf.port(0), i);
428  registers[i] = reg;
429  if (i > REG_SP) {
430  allParamRegs_.insert(reg);
431  }
432  }
433 }

References allParamRegs_, UniversalMachine::integerRegisterFile(), TTAMachine::BaseRegisterFile::port(), REG_SP, and DisassemblyRegister::registerName().

Here is the call graph for this function:

◆ findStaticRegisters() [2/4]

void DataDependenceGraphBuilder::findStaticRegisters ( ControlFlowGraph cfg,
std::map< int, TCEString > &  registers 
)
protected

Tries to find annotations which tell the static registers from a program.

Used only with the old gcc frontend.

Parameters
cfgcfg where to search the annotations.

Definition at line 324 of file DataDependenceGraphBuilder.cc.

326  {
327  for (int i = 0; i < cfg.nodeCount(); i++) {
328  BasicBlockNode& bbn = cfg.node(i);
329  if (bbn.isNormalBB()) {
330  findStaticRegisters(bbn.basicBlock(), registers);
331  }
332  }
333 }

References BasicBlockNode::basicBlock(), findStaticRegisters(), BasicBlockNode::isNormalBB(), BoostGraph< GraphNode, GraphEdge >::node(), and BoostGraph< GraphNode, GraphEdge >::nodeCount().

Here is the call graph for this function:

◆ findStaticRegisters() [3/4]

void DataDependenceGraphBuilder::findStaticRegisters ( TTAProgram::CodeSnippet cs,
std::map< int, TCEString > &  registers 
)
protected

find special register data from old frontend code

Tries to find annotations which tell the static registers from a program.

Used only with the old gcc frontend.

Parameters
cscodesnippet where to search the annotations.

Definition at line 306 of file DataDependenceGraphBuilder.cc.

308  {
309  for (int i = 0; i < cs.instructionCount(); i++) {
310  Instruction& ins = cs.instructionAtIndex(i);
311  findStaticRegisters(ins, registers);
312  }
313 }

References TTAProgram::CodeSnippet::instructionAtIndex(), and TTAProgram::CodeSnippet::instructionCount().

Referenced by build(), and findStaticRegisters().

Here is the call graph for this function:

◆ findStaticRegisters() [4/4]

void DataDependenceGraphBuilder::findStaticRegisters ( TTAProgram::Instruction ins,
std::map< int, TCEString > &  registers 
)
protected

Tries to find annotations which tell the static registers from a program.

Used only with the old gcc frontend.

Parameters
insinstruction where to search the annotations.

Definition at line 344 of file DataDependenceGraphBuilder.cc.

346  {
347 
348  try {
349  for (int i = 0; i < ins.moveCount(); i++) {
350  Move& move = ins.move(i);
351  for (int j = 0; j < move.annotationCount(); j++) {
352  ProgramAnnotation anno = move.annotation(j);
353  switch (anno.id()) {
354  case ProgramAnnotation::ANN_REGISTER_RV_READ: {
356  move.source());
357  break;
358  }
359  case ProgramAnnotation::ANN_REGISTER_RV_SAVE: {
361  move.destination());
362  break;
363  }
364  case ProgramAnnotation::ANN_REGISTER_SP_READ: {
366  move.source());
367  break;
368  }
369  case ProgramAnnotation::ANN_REGISTER_SP_SAVE: {
371  move.destination());
372  break;
373  }
374  case ProgramAnnotation::ANN_REGISTER_IPARAM_READ: {
375 /* this fixes one unit test silent breakage but another will then happen - unit test
376  tpef's seem to contain a bit broken code
377  Terminal& src = move.source();
378  if (!src.isGPR()) {
379  break;
380  }
381 */
382  TCEString reg =
384  registers[
386  reg;
387  allParamRegs_.insert(reg);
388  break;
389  }
390  case ProgramAnnotation::ANN_REGISTER_IPARAM_SAVE: {
391  TCEString reg =
393  registers[
395  reg;
396  allParamRegs_.insert(reg);
397  break;
398  }
399  default:
400  //TODO: frame pointer, not yet implemented
401  break;
402  }
403  }
404  }
405  } catch (std::bad_cast& e) {
406  throw IllegalProgram(__FILE__,__LINE__, __func__, "Illegal annotation");
407  }
408 }

References __func__, allParamRegs_, TTAProgram::AnnotatedInstructionElement::annotation(), TTAProgram::AnnotatedInstructionElement::annotationCount(), TTAProgram::Move::destination(), TTAProgram::ProgramAnnotation::id(), TTAProgram::Instruction::move(), TTAProgram::Instruction::moveCount(), REG_IPARAM, REG_RV, REG_SP, DisassemblyRegister::registerName(), TTAProgram::Move::source(), TTAProgram::ProgramAnnotation::stringValue(), and Conversion::toInt().

Here is the call graph for this function:

◆ hasEarlierMemWriteToSameAddressWithSameGuard()

bool DataDependenceGraphBuilder::hasEarlierMemWriteToSameAddressWithSameGuard ( MoveNodeUse mnd,
std::set< MoveNodeUse > &  defines 
)
protected

Checks if there is an earlier write to same address or with same guard.

Parameters
mndthe current node dictating guard and mem address to check.
definesset of earlier writes to check for the write.

Definition at line 1688 of file DataDependenceGraphBuilder.cc.

1689  {
1690  // first just check if there is earlier write to this mem address
1691  // with same guard.
1692  for (std::set<MoveNodeUse>::iterator i = defines.begin();
1693  i != defines.end(); i++) {
1694  // if earlier write to this reg with same guard..
1695  if (currentDDG_->sameGuards(*(i->mn()), *(mnd.mn()))) {
1696  ProgramOperation& curPop = mnd.mn()->destinationOperation();
1697  ProgramOperation& prevPop = (i->mn())->destinationOperation();
1698 // MoveNode* currentAddress = addressMove(*mnd.mn());
1699 // MoveNode* prevAddress = addressMove(*(i->mn()));
1700  if (!isAddressTraceable(prevPop) ||
1701  analyzeMemoryAlias(prevPop, curPop, i->bbRelation()) ==
1703  return true;
1704  }
1705  }
1706  }
1707  return false;
1708 }

References MemoryAliasAnalyzer::ALIAS_TRUE, analyzeMemoryAlias(), currentDDG_, MoveNode::destinationOperation(), isAddressTraceable(), MoveNodeUse::mn(), and DataDependenceGraph::sameGuards().

Referenced by processMemUse(), and processMemWrite().

Here is the call graph for this function:

◆ hasEarlierWriteWithSameGuard()

bool DataDependenceGraphBuilder::hasEarlierWriteWithSameGuard ( MoveNodeUse mnd,
std::set< MoveNodeUse > &  defines 
)
protected

Checks whether there is a previous alive write with same guard than given node.

The origin of the guard value is tracked from DDG, not only plain guard is done.

Parameters
mndMoveNode containing the guard.
definesset of earlier writes which to check.

Definition at line 1183 of file DataDependenceGraphBuilder.cc.

1184  {
1185 
1186  // first just check if there is earlier write to this reg with same guard..
1187  for (std::set<MoveNodeUse>::iterator i = defines.begin();
1188  i != defines.end(); i++) {
1189  // if earlier write to this reg with same guard..
1190  if (!mnd.guard() &&
1191  !i->mn()->move().isUnconditional() &&
1192  currentDDG_->sameGuards(*(i->mn()), *(mnd.mn()))) {
1193  return true;
1194  }
1195  }
1196  return false;
1197 }

References currentDDG_, MoveNodeUse::guard(), MoveNodeUse::mn(), and DataDependenceGraph::sameGuards().

Referenced by processRegWrite().

Here is the call graph for this function:

◆ initializeBBStates()

void DataDependenceGraphBuilder::initializeBBStates ( )
protected

Initializes states of all BB's to unreached

Definition at line 2191 of file DataDependenceGraphBuilder.cc.

2191  {
2192 
2193  // initialize state lists
2194  for (int bbi = 0; bbi < cfg_->nodeCount(); bbi++) {
2195  BasicBlockNode& bbn = cfg_->node(bbi);
2196  BasicBlock& bb = bbn.basicBlock();
2197  if (bb.liveRangeData_ == NULL) {
2198  bb.liveRangeData_ = new LiveRangeData;
2199  }
2200  BBData* bbd = new BBData(bbn);
2201  bbData_[&bbn] = bbd;
2202  // in the beginning all are unreached
2203  if (bbn.isNormalBB()) {
2204  blocksByState_[BB_UNREACHED].push_back(bbd);
2205  }
2206  }
2207 }

References BasicBlockNode::basicBlock(), BB_UNREACHED, bbData_, blocksByState_, cfg_, BasicBlockNode::isNormalBB(), TTAProgram::BasicBlock::liveRangeData_, BoostGraph< GraphNode, GraphEdge >::node(), and BoostGraph< GraphNode, GraphEdge >::nodeCount().

Referenced by createMemAndFUstateDeps(), createRegisterDeps(), and searchRegisterDeaths().

Here is the call graph for this function:

◆ isAddressTraceable()

bool DataDependenceGraphBuilder::isAddressTraceable ( const ProgramOperation pop)
protected

Can some analyzer say something about this address?

Parameters
mnMovenode containing memory address write.
Returns
true if some alias analyzer knows something about the address, ie can return something else than ALIAS_UNKNOWN.

Definition at line 1974 of file DataDependenceGraphBuilder.cc.

1974  {
1975 
1976  for (unsigned int i = 0; i < aliasAnalyzers_.size(); i++) {
1977  if (aliasAnalyzers_.at(i)->isAddressTraceable(*currentDDG_, pop)) {
1978  return true;
1979  }
1980  }
1981  return false;
1982 }

References aliasAnalyzers_, and currentDDG_.

Referenced by hasEarlierMemWriteToSameAddressWithSameGuard(), and processMemWrite().

◆ isAlwaysDifferentFU()

bool DataDependenceGraphBuilder::isAlwaysDifferentFU ( const MoveNode srcMN,
const MoveNode dstMN 
)
protected

Check if operations are assigned to differnt FU

Operations forced to different FUs are independent since the operation state is per FU. Check if the moves have forced set of FUs and if the sets overlap.

Parameters
srcMNMoveNode first node for dependency check
dstMNMoveNode for which dependency needs to be checked
Returns
Nodes are alawys mapped to different FU

Definition at line 2994 of file DataDependenceGraphBuilder.cc.

2995  {
2996  if (srcMN->move().hasAnnotations(
2998  dstMN->move().hasAnnotations(
3000  bool alwaysDifferentFUs = true;
3001  for (int idx = 0;
3002  idx < srcMN->move().annotationCount(
3004  ++idx) {
3005  if (dstMN->move().hasAnnotation(
3007  srcMN->move()
3008  .annotation(
3010  ANN_ALLOWED_UNIT_DST)
3011  .stringValue())) {
3012  alwaysDifferentFUs = false;
3013  break;
3014  }
3015  }
3016  return alwaysDifferentFUs;
3017  }
3018  return false;
3019 }

References TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_DST, TTAProgram::AnnotatedInstructionElement::annotation(), TTAProgram::AnnotatedInstructionElement::hasAnnotation(), TTAProgram::AnnotatedInstructionElement::hasAnnotations(), MoveNode::move(), and TTAProgram::ProgramAnnotation::stringValue().

Referenced by checkAndCreateMemDep(), and createSideEffectEdges().

Here is the call graph for this function:

◆ isTriggering()

bool DataDependenceGraphBuilder::isTriggering ( const MoveNode mn)
protected

Definition at line 810 of file DataDependenceGraphBuilder.cc.

810  {
811  int destIndex = mn.move().destination().operationIndex();
812  const Operation& op = mn.destinationOperation().operation();
813  int triggerIndex = MachineInfo::triggerIndex(*mach_, op);
814  switch (triggerIndex) {
815  case -1: {
816  TCEString msg = "Trigger index ambiguous for operation: ";
817  msg << op.name() << " in the machine.";
818  throw IllegalMachine(__FILE__,__LINE__,__func__, msg);
819  break;
820  }
821  case 0: {
822  TCEString msg = "Operation: ";
823  msg << op.name() << " Not found from the machine";
824  throw CompileError(__FILE__,__LINE__,__func__, msg);
825  break;
826  }
827  default:
828  return triggerIndex == destIndex;
829  }
830 }

References __func__, TTAProgram::Move::destination(), MoveNode::destinationOperation(), mach_, MoveNode::move(), Operation::name(), ProgramOperation::operation(), TTAProgram::Terminal::operationIndex(), and MachineInfo::triggerIndex().

Referenced by processDestination().

Here is the call graph for this function:

◆ iterateBBs()

void DataDependenceGraphBuilder::iterateBBs ( ConstructionPhase  phase)
protected

Iterates over basic blocks as long as there is some BB to process.

Handles a BB, updates the live value lists of its successors. If incoming live values of a BB change, it's scheduled for reprocessing.

Parameters
phasewhether to handle register& operation deps or memory and side-effect dependencies.

Definition at line 2345 of file DataDependenceGraphBuilder.cc.

2346  {
2347 
2348  while (!blocksByState_[BB_QUEUED].empty()) {
2349  std::list<BBData*>::iterator bbIter =
2350  blocksByState_[BB_QUEUED].begin();
2351  BBData& bbd = **bbIter;
2352 
2353  // construct or update BB
2354  if (bbd.constructed_) {
2355  updateBB(bbd, phase);
2356  } else {
2357  constructIndividualBB(bbd, phase);
2358  }
2359  // mark as ready
2360  changeState(bbd, BB_READY);
2361 
2362  // create deps after and update that to succeeding BBs.
2363  // succeeding BB's are also queued to be scheduled here.
2364  // queue succeeding BB's in case either
2365  // * their input data has changed
2366  // * current BB was processed for the first time
2367  if (phase == REGISTERS_AND_PROGRAM_OPERATIONS) {
2368  if (updateRegistersAliveAfter(bbd) || !bbd.constructed_) {
2369  setSucceedingPredeps(bbd, !bbd.constructed_, phase);
2370  }
2371  } else {
2372  if (updateMemAndFuAliveAfter(bbd) || !bbd.constructed_) {
2373  setSucceedingPredeps(bbd, !bbd.constructed_, phase);
2374  }
2375  }
2376 
2377  bbd.constructed_ = true;
2378  }
2379 }

References BB_QUEUED, BB_READY, blocksByState_, changeState(), DataDependenceGraphBuilder::BBData::constructed_, constructIndividualBB(), REGISTERS_AND_PROGRAM_OPERATIONS, setSucceedingPredeps(), updateBB(), updateMemAndFuAliveAfter(), and updateRegistersAliveAfter().

Referenced by createMemAndFUstateDeps(), and createRegisterDeps().

Here is the call graph for this function:

◆ iterateRegisterDeaths()

void DataDependenceGraphBuilder::iterateRegisterDeaths ( )
protected

Iterates thru all queued BB's and find register deaths from them.

Loops as long as something keeps changing.

Definition at line 2924 of file DataDependenceGraphBuilder.cc.

2924  {
2925 
2926  // loop as long as we have unprocessed/changed BB's
2927  while (!blocksByState_[BB_QUEUED].empty()) {
2928  std::list<BBData*>::iterator bbIter =
2929  blocksByState_[BB_QUEUED].begin();
2930  BBData& bbd = **bbIter;
2931 
2932  // mark as ready
2933  changeState(bbd, BB_READY);
2934 
2935  if (updateRegistersUsedInOrAfter(bbd) || (!bbd.constructed_)) {
2936  // if there asre more registers read after start of this BB,
2937  // have to update this information to preceedign BBs,
2938  // and check if they need to be reprocessed.
2939  updatePreceedingRegistersUsedAfter(bbd, !bbd.constructed_);
2940  }
2941  bbd.constructed_ = true;
2942  }
2943 }

References BB_QUEUED, BB_READY, blocksByState_, changeState(), DataDependenceGraphBuilder::BBData::constructed_, updatePreceedingRegistersUsedAfter(), and updateRegistersUsedInOrAfter().

Referenced by searchRegisterDeaths().

Here is the call graph for this function:

◆ memoryCategory()

TCEString DataDependenceGraphBuilder::memoryCategory ( const MoveNodeUse mnd)
protected

Checks into which category this memory address belongs.

Memory accesses in different categories cannot alias, and there is separate bookkeeping for every category. Current implementation separates spills, different alias spaces, restrict keywords and opencl work items.

Parameters
mndMoveNodeUse which transfers the address of the memory operation.
Returns
string which is then used as key for map. unique for different categories, empty for the default category.

@TODO: create some memorycategorizer interface for this analysis?

Definition at line 1999 of file DataDependenceGraphBuilder.cc.

1999  {
2000 
2001  TCEString category;
2002 
2003 // MoveNode* addressNode = addressMove(*mnd.mn());
2004 // if (addressNode != NULL && addressNode->isMove()) {
2005  const TTAProgram::Move& move = mnd.mn()->move();//addressNode->move();
2006 
2007  // spill annotations are in all operands.
2008  for (int j = 0; j < move.annotationCount(); j++) {
2010  if (anno.id() ==
2012  return "_SPILL";
2013  }
2014  if (anno.id() ==
2016  return "_RA";
2017  }
2018  if (anno.id() ==
2020  return "_FP";
2021  }
2022  if (anno.id() ==
2024  return "_CONSTANT";
2025  }
2026  }
2027  if (!mnd.mn()->isDestinationOperation()) {
2028  PRINT_VAR(mnd.mn()->toString());
2029  abortWithError("Not destination operation!");
2030  }
2031  ProgramOperation& po = mnd.mn()->destinationOperation();
2032 
2033  LLVMTCECmdLineOptions* llvmOptions =
2034  dynamic_cast<LLVMTCECmdLineOptions*>(
2036  if (llvmOptions == NULL || !llvmOptions->disableAddressSpaceAA()) {
2037  // address space
2038  for (int i = 0; i < po.inputMoveCount(); i++) {
2039  MoveNode& mn = po.inputMove(i);
2040  Move& m = mn.move();
2041  if (m.hasAnnotations(
2042  ProgramAnnotation::ANN_POINTER_ADDR_SPACE)) {
2043  if (m.annotation(
2044  0, ProgramAnnotation::ANN_POINTER_ADDR_SPACE).stringValue()
2045  != "0") {
2046  category +=
2047  "_AS:" +
2048  m.annotation(
2049  0, ProgramAnnotation::ANN_POINTER_ADDR_SPACE)
2050  .stringValue();
2051  break;
2052  }
2053  }
2054  }
2055  }
2056  for (int i = 0; i < po.inputMoveCount(); i++) {
2057  MoveNode& mn = po.inputMove(i);
2058  Move& m = mn.move();
2059  TCEString pointerName = "";
2060  // restrict keyword.
2061  if (m.hasAnnotations(
2062  ProgramAnnotation::ANN_POINTER_NAME) &&
2063  m.hasAnnotations(
2064  ProgramAnnotation::ANN_POINTER_NOALIAS)) {
2065  pointerName =
2066  m.annotation(
2067  0, ProgramAnnotation::ANN_POINTER_NAME).stringValue();
2068  category += "_RESTRICT:" + pointerName;
2069  break;
2070  }
2071  }
2072 
2073  /* OpenCL work item variable access.
2074 
2075  OpenCL kernels enforce memory consistency for local and global
2076  memory only at explicit barrier() calls within a work group.
2077  Thus, all memory accesses between work items can be considered
2078  independent in alias analysis in the regions between barrier
2079  calls.
2080  */
2081  for (int i = 0; i < po.inputMoveCount(); i++) {
2082  MoveNode& mn = po.inputMove(i);
2083  Move& m = mn.move();
2084  if (m.hasAnnotations(ProgramAnnotation::ANN_OPENCL_WORK_ITEM_ID)) {
2085  category +=
2086  "_OPENCL_WI:" +
2088  m.annotation(
2089  0, ProgramAnnotation::ANN_OPENCL_WORK_ITEM_ID).
2090  intValue(), 8);
2091  break;
2092  }
2093  }
2094  return category;
2095 }

References abortWithError, TTAProgram::ProgramAnnotation::ANN_CONSTANT_MEM, TTAProgram::ProgramAnnotation::ANN_STACKUSE_FP_SAVE, TTAProgram::ProgramAnnotation::ANN_STACKUSE_RA_SAVE, TTAProgram::ProgramAnnotation::ANN_STACKUSE_SPILL, TTAProgram::AnnotatedInstructionElement::annotation(), TTAProgram::AnnotatedInstructionElement::annotationCount(), Application::cmdLineOptions(), MoveNode::destinationOperation(), LLVMTCECmdLineOptions::disableAddressSpaceAA(), TTAProgram::AnnotatedInstructionElement::hasAnnotations(), TTAProgram::ProgramAnnotation::id(), ProgramOperation::inputMove(), ProgramOperation::inputMoveCount(), MoveNode::isDestinationOperation(), MoveNodeUse::mn(), MoveNode::move(), PRINT_VAR, TTAProgram::ProgramAnnotation::stringValue(), Conversion::toHexString(), and MoveNode::toString().

Referenced by processMemUse(), and processMemWrite().

Here is the call graph for this function:

◆ processCall()

void DataDependenceGraphBuilder::processCall ( MoveNode mn)
protected

Processes a call of a function.

Pseudo-reads from parameter registers and SP, writes to RV and RA.

Parameters
mnMoveNode containg the function call move.

Definition at line 1532 of file DataDependenceGraphBuilder.cc.

1532  {
1533 
1534  // calls mess up RA. But immediately, not after delay slots?
1536  MoveNodeUse(mn, false, true, false), RA_NAME);
1537 
1538  // MoveNodeUse for sp and rv(not guard, not ra, is pseudo)
1539  MoveNodeUse mnd2(mn, false,false, true);
1540 
1541  // call is considered read of sp
1543  if (sp != "") {
1544  processRegUse(mnd2,sp);
1545  }
1546 
1547  // call is considered as write of RV
1549  if (rv != "") {
1550  if (rvIsParamReg_) {
1551  processRegUse(mnd2,rv);
1552  }
1553  processRegWrite(mnd2,rv);
1554  }
1555 
1556  // process all vector rv values
1557  for (int i = REG_VRV;;i--) {
1558  auto vrvIt = specialRegisters_.find(i);
1559  if (vrvIt != specialRegisters_.end()) {
1560  processRegWrite(mnd2, vrvIt->second);
1561  } else {
1562  break;
1563  }
1564  }
1565 
1566  // call is considered as write of RV high (64-bit return values)
1568  if (rvh != "") {
1569  processRegWrite(mnd2, rvh);
1570  }
1571 
1572  // params
1573  for (int i = 0; i < 4;i++) {
1574  TCEString paramReg = specialRegisters_[REG_IPARAM+i];
1575  if (paramReg != "") {
1576  processRegUse(mnd2, paramReg);
1577  }
1578  }
1579 }

References processRegUse(), processRegWrite(), RA_NAME, REG_IPARAM, REG_RV, REG_RV_HIGH, REG_SP, REG_VRV, rvIsParamReg_, and specialRegisters_.

Referenced by processTriggerRegistersAndOperations().

Here is the call graph for this function:

◆ processDestination()

void DataDependenceGraphBuilder::processDestination ( class MoveNode moveNode,
ConstructionPhase  phase 
)
protected

Analyzes destination of a move. Updates bookkeeping and handles WaW and WaR dependencies of the move.

Checks whether destination is operation or register and calls other functions to do the actual dependence checks etc.

Parameters
moveNodeMoveNode whose destination is being processed.
phasewhether to handle register& operation deps or memory and side-effect dependencies.

Definition at line 844 of file DataDependenceGraphBuilder.cc.

845  {
846  Terminal& dest = moveNode.move().destination();
847 
848  // is this a operand to an operation?
849  if (dest.isFUPort()) {
850  if (!(dynamic_cast<const SpecialRegisterPort*>(&dest.port()))) {
851  TerminalFUPort& tfpd = dynamic_cast<TerminalFUPort&>(dest);
852  Operation &dop = tfpd.hintOperation();
853 
854  if (phase == REGISTERS_AND_PROGRAM_OPERATIONS) {
855  if (tfpd.isOpcodeSetting()) {
857  moveNode, dop);
858  } else {
859  processOperand(moveNode, dop);
860  }
861  } else { // memory and fu state deps
862  if (dop.usesMemory() || dop.hasSideEffects() ||
863  dop.affectsCount() || dop.affectedByCount() ||
864  moveNode.move().isControlFlowMove()) {
865  if (isTriggering(moveNode)) {
866  processTriggerMemoryAndFUStates(moveNode, dop);
867  }
868  }
869  }
870  } else { // RA write
871  if (phase == REGISTERS_AND_PROGRAM_OPERATIONS) {
872  processRegWrite(MoveNodeUse(moveNode,false,true), RA_NAME);
873  }
874  }
875  } else {
876  if (dest.isGPR()) {
877  // we do not care about register reads in second phase
878  if (phase == REGISTERS_AND_PROGRAM_OPERATIONS) {
879  TerminalRegister& tr = dynamic_cast<TerminalRegister&>(dest);
881  processRegWrite(MoveNodeUse(moveNode), regName);
882  }
883  } else { // something else
884  throw IllegalProgram(__FILE__,__LINE__,__func__,
885  "Move has illegal destination" +
886  moveNode.toString());
887  }
888  }
889 }

References __func__, Operation::affectedByCount(), Operation::affectsCount(), TTAProgram::Move::destination(), Operation::hasSideEffects(), TTAProgram::TerminalFUPort::hintOperation(), TTAProgram::Move::isControlFlowMove(), TTAProgram::Terminal::isFUPort(), TTAProgram::Terminal::isGPR(), TTAProgram::TerminalFUPort::isOpcodeSetting(), isTriggering(), MoveNode::move(), TTAProgram::Terminal::port(), processOperand(), processRegWrite(), processTriggerMemoryAndFUStates(), processTriggerRegistersAndOperations(), RA_NAME, DisassemblyRegister::registerName(), REGISTERS_AND_PROGRAM_OPERATIONS, MoveNode::toString(), and Operation::usesMemory().

Referenced by constructIndividualBB().

Here is the call graph for this function:

◆ processEntryNode()

void DataDependenceGraphBuilder::processEntryNode ( MoveNode mn)
protected

Processes the pseudo deps from entry node.

This procedure must be called when currentBB is the first real BB of the procedure.

Definition at line 2694 of file DataDependenceGraphBuilder.cc.

2694  {
2695 
2696  // initializes RA
2698 
2699  // sp
2700  MoveNodeUse mnd2(mn);
2702  if (sp != "") {
2703  currentBB_->basicBlock().liveRangeData_->regDefReaches_[sp].insert(mnd2);
2704  }
2705 
2706  if (rvIsParamReg_) {
2708  if (rv != "") {
2710  mnd2);
2711  }
2712  }
2713 
2714  // params
2715  // this is for old frontend generated code.
2716  for (int i = 0;;i++) {
2717  TCEString paramReg = specialRegisters_[REG_IPARAM+i];
2718  if(paramReg != "") {
2719  currentBB_->basicBlock().liveRangeData_->regDefReaches_[paramReg].insert(mnd2);
2720  } else {
2721  break;
2722  }
2723  }
2724 
2726  if (fp != "") {
2728  mnd2);
2729  }
2730 }

References BasicBlockNode::basicBlock(), currentBB_, TTAProgram::BasicBlock::liveRangeData_, RA_NAME, REG_FP, REG_IPARAM, REG_RV, REG_SP, LiveRangeData::regDefReaches_, rvIsParamReg_, and specialRegisters_.

Referenced by createRegisterDeps().

Here is the call graph for this function:

◆ processGuard()

void DataDependenceGraphBuilder::processGuard ( MoveNode moveNode)
protected

Analyzes dependencies related to guard usage.

Finds the guard register used for the guard and the move Which writes the guard register, and creates a guard egde between them.

Parameters
moveNodeMNData of move containing guarded move.

Definition at line 760 of file DataDependenceGraphBuilder.cc.

760  {
761 
762  // new code
763  const Guard& g = moveNode.move().guard().guard();
764  const RegisterGuard* rg = dynamic_cast<const RegisterGuard*>(&g);
765  if (rg != NULL) {
766  TCEString regName = rg->registerFile()->name() + '.' +
768  processRegUse(MoveNodeUse(moveNode, true),regName);
769  } else {
770  throw IllegalProgram(
771  __FILE__,__LINE__,__func__,
772  "Analysis for port guards not supported! used in: "
773  + moveNode.toString());
774  }
775 }

References __func__, TTAProgram::MoveGuard::guard(), TTAProgram::Move::guard(), MoveNode::move(), TTAMachine::Component::name(), processRegUse(), TTAMachine::RegisterGuard::registerFile(), TTAMachine::RegisterGuard::registerIndex(), Conversion::toString(), and MoveNode::toString().

Referenced by constructIndividualBB().

Here is the call graph for this function:

◆ processMemUse()

void DataDependenceGraphBuilder::processMemUse ( MoveNodeUse  mnd)
protected

Processes a memory read.

Creates dependence edges and updates bookkeeping.

Parameters
mndMoveNodeUse of MoveNode being processed.

Definition at line 1800 of file DataDependenceGraphBuilder.cc.

1800  {
1801 
1802  TCEString category = memoryCategory(mnd);
1803 
1804  // can be multiple if some write predicated
1805  std::set<MoveNodeUse>& defines =
1807 
1808  // no kills/barriers to this one in this basic block.
1809  if (currentBB_->basicBlock().liveRangeData_->memKills_[category].mn() == NULL) {
1810 
1811  // check if there is "guarded kill" to this mem address
1812  bool guardedKillFound =
1814 
1815  if (!guardedKillFound) {
1816  currentBB_->basicBlock().liveRangeData_->memFirstUses_[category].insert(mnd);
1817  // so create deps from previous BB's
1818  updateMemUse(mnd, category);
1819  }
1820  }
1821 
1822  // create deps from writes in this BB.LIVERANGEDATA_->
1823  for (MoveNodeUseSet::iterator iter =
1824  defines.begin(); iter != defines.end(); iter++) {
1826  }
1827  // update bookkeeping.
1828  currentBB_->basicBlock().liveRangeData_->memLastUses_[category].insert(mnd);
1829 }

References BasicBlockNode::basicBlock(), checkAndCreateMemDep(), currentBB_, DataDependenceEdge::DEP_RAW, hasEarlierMemWriteToSameAddressWithSameGuard(), TTAProgram::BasicBlock::liveRangeData_, LiveRangeData::memDefines_, LiveRangeData::memFirstUses_, LiveRangeData::memKills_, LiveRangeData::memLastUses_, memoryCategory(), and updateMemUse().

Referenced by createTriggerDependencies().

Here is the call graph for this function:

◆ processMemWrite()

void DataDependenceGraphBuilder::processMemWrite ( MoveNodeUse  mnd)
protected

Updates memory operation bookkeeping and creates WaR and WaW memory dependencies.

Parameters
moveNodeMoveNodeUse related to Move whose memory write to are processing.

Definition at line 1744 of file DataDependenceGraphBuilder.cc.

1744  {
1745 
1746  TCEString category = memoryCategory(mnd);
1747 
1748  std::set<MoveNodeUse>& defines =
1750 
1751  std::set<MoveNodeUse>& lastUses =
1753 
1754  // check if no earlier barriers/kills to this one in this bb?
1755  if (currentBB_->basicBlock().liveRangeData_->memKills_[category].mn() == NULL) {
1756 
1757  // is this a kill?
1758  if (mnd.mn()->move().isUnconditional() &&
1760  currentBB_->basicBlock().liveRangeData_->memKills_[category] = mnd;
1761  }
1762 
1763  // check if there is "guarded kill" to this mem address
1764  bool guardedKillFound =
1766 
1767  if (!guardedKillFound) {
1768  // may have incoming WaW's / WaRs to this
1769  currentBB_->basicBlock().liveRangeData_->memFirstDefines_[category].insert(mnd);
1770  updateMemWrite(mnd, category);
1771  }
1772  }
1773 
1774  bool traceable = isAddressTraceable(mnd.mn()->destinationOperation());
1775 
1777  mnd, defines, DataDependenceEdge::DEP_WAW, traceable);
1778 
1780  mnd, lastUses, DataDependenceEdge::DEP_WAR, traceable);
1781 
1782  // does this kill previous deps?
1783  if (mnd.mn()->move().isUnconditional() && !traceable) {
1784  currentBB_->basicBlock().liveRangeData_->memLastKill_[category] = mnd;
1785  defines.clear();
1786  lastUses.clear();
1787  }
1788 
1789  defines.insert(mnd);
1790 }

References BasicBlockNode::basicBlock(), checkAndCreateMemAntideps(), currentBB_, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, MoveNode::destinationOperation(), hasEarlierMemWriteToSameAddressWithSameGuard(), isAddressTraceable(), TTAProgram::Move::isUnconditional(), TTAProgram::BasicBlock::liveRangeData_, LiveRangeData::memDefines_, LiveRangeData::memFirstDefines_, LiveRangeData::memKills_, LiveRangeData::memLastKill_, LiveRangeData::memLastUses_, memoryCategory(), MoveNodeUse::mn(), MoveNode::move(), and updateMemWrite().

Referenced by createTriggerDependencies(), and processTriggerMemoryAndFUStates().

Here is the call graph for this function:

◆ processOperand()

void DataDependenceGraphBuilder::processOperand ( class MoveNode moveNode,
Operation dop 
)
protected

Analyzes operand writes.

Part of ProgramOperation creation.

Parameters
moveNodemnData related to a move which writes a parameter.
dopOperation whose parameter is being written.

Definition at line 1062 of file DataDependenceGraphBuilder.cc.

1063  {
1064 
1065  // first operands already analyzed for PO?
1066  // then update existing.
1067  if (currentData_->destPending_ != NULL) {
1069 
1070  assert(&dop == &po->operation());
1071 
1072  if (!po->isComplete()) {
1073  po->addInputNode(moveNode);
1074  moveNode.addDestinationOperationPtr(po);
1075  } else {
1076  // The MoveNode and the PO has been created before entering DDG
1077  // building (in LLVMTCEBuilder.cc).
1078  }
1079  return;
1080  }
1081 
1082  // create a new ProgramOperation
1083  TerminalFUPort& tfpd =
1084  dynamic_cast<TerminalFUPort&>(moveNode.move().destination());
1086  if (tfpd.hasProgramOperation()) {
1087  po = tfpd.programOperation();
1088  } else {
1089  po = ProgramOperationPtr(new ProgramOperation(dop));
1090  moveNode.addDestinationOperationPtr(po);
1091  po->addInputNode(moveNode);
1092  }
1093  currentData_->destPending_ = po;
1094 }

References MoveNode::addDestinationOperationPtr(), assert, currentData_, TTAProgram::Move::destination(), DataDependenceGraphBuilder::BBData::destPending_, TTAProgram::TerminalFUPort::hasProgramOperation(), MoveNode::move(), and TTAProgram::TerminalFUPort::programOperation().

Referenced by processDestination().

Here is the call graph for this function:

◆ processRegUse()

void DataDependenceGraphBuilder::processRegUse ( MoveNodeUse  mnd,
const TCEString reg 
)
protected

Handles a usage of a register value.

The usage can be either register read or guard usage. Creates the incoming edges and handles bookkeping related to the register read.

Parameters
mndData about the register use
regRegister containing the value being used.

Definition at line 1229 of file DataDependenceGraphBuilder.cc.

1230  {
1231 
1232  // We may have multiple definitions to a register alive
1233  // (statically) at same time if some of the writes were guarded,
1234  // so we don't know which of them were actually executed,
1235  // so we have a set instead of single value.
1236  std::set<MoveNodeUse>& defines =
1238 
1239  std::set<MoveNodeUse> sameGuardDefines = earlierWritesWithSameGuard(mnd, defines);
1240  // find if we have a earlier write with same guard. In this case
1241  // no need to draw dependencies over it.
1242  bool guardedKillFound = !sameGuardDefines.empty();
1243 
1244  // then create the edges. if no guarded kill found,
1245  // all non-exclusive. if guarded kill found, not to uncond move.
1246  for (std::set<MoveNodeUse>::iterator i = defines.begin();
1247  i != defines.end(); i++) {
1248  // If we do not have a guarded kill, draw edges from all defines.
1249  // If we have a guarded kill, only draw edges from
1250  // unconditional moves, as the guarded kill overshadows the
1251  // inconditional writes.
1252  if (!guardedKillFound || (!i->mn()->move().isUnconditional() &&
1253  !currentDDG_->hasRegWaw(*i, sameGuardDefines))) {
1254  if (!currentDDG_->exclusingGuards(*(i->mn()), *(mnd.mn()))) {
1255  DataDependenceEdge* dde =
1256  new DataDependenceEdge(
1259  DataDependenceEdge::DEP_RAW, reg, mnd.guard(), false,
1260  i->pseudo(), mnd.pseudo(), i->loop());
1261 
1262  currentDDG_->connectOrDeleteEdge(*i->mn(), *mnd.mn(), dde);
1263  }
1264  }
1265  }
1266 
1267  // writes in previous BB's killed or not?
1268  // if not(this bb has a kill), has to check deps from incoming BB's.
1269  if (currentBB_->basicBlock().liveRangeData_->regKills_.find(reg) ==
1271 
1272  if (!guardedKillFound) {
1273  // process dependencies from previous BB's
1275  insert(mnd);
1276 
1278  }
1279  }
1280  currentBB_->basicBlock().liveRangeData_->regLastUses_[reg].insert(mnd);
1281 
1282  // Two writes to opposite guard may create a combined kill-pair.
1283  // But if this is a read between them, it has to be marked in order
1284  // to save bookkeeping about this move when the another write occurs.
1285  // So mark here that we have a read if we have one guarded write
1286  // in our bookkeeping as potential half of a kill pair.
1287  std::map<TCEString, std::pair<MoveNodeUse, bool> >::iterator iter =
1289  if (iter != currentBB_->basicBlock().liveRangeData_->potentialRegKills_.end()) {
1290  iter->second.second = true;
1291  }
1292 }

References BasicBlockNode::basicBlock(), DataDependenceGraph::connectOrDeleteEdge(), currentBB_, currentDDG_, DataDependenceEdge::DEP_RAW, earlierWritesWithSameGuard(), DataDependenceEdge::EDGE_RA, DataDependenceEdge::EDGE_REGISTER, DataDependenceGraph::exclusingGuards(), MoveNodeUse::guard(), DataDependenceGraph::hasRegWaw(), TTAProgram::BasicBlock::liveRangeData_, MoveNodeUse::mn(), LiveRangeData::potentialRegKills_, MoveNodeUse::pseudo(), MoveNodeUse::ra(), LiveRangeData::regDefines_, LiveRangeData::regFirstUses_, LiveRangeData::regKills_, LiveRangeData::regLastUses_, and DataDependenceGraph::updateRegUse().

Referenced by processCall(), processGuard(), processReturn(), and processSource().

Here is the call graph for this function:

◆ processRegWrite()

void DataDependenceGraphBuilder::processRegWrite ( MoveNodeUse  mnd,
const TCEString reg 
)
protected

Analyzes a write to a register.

Creates dependence edges and updates bookkeeping.

Parameters
mndMoveNodeUse containing MoveNode that writes a register
regregister being written by the given movenode.

Definition at line 1369 of file DataDependenceGraphBuilder.cc.

1370  {
1371 
1372  // We may have multiple definitions to a register alive
1373  // (statically) at same time if some of the writes were guarded,
1374  // so we don't know which of them were actually executed,
1375  // so we have a set instead of single value.
1376  std::set<MoveNodeUse>& defines =
1378 
1379  // Set of register reads which after last kill.
1380  std::set<MoveNodeUse>& lastUses =
1382 
1383  // find if we have a earlier write with same guard. In this case
1384  // no need to draw dependencies over it.
1385  bool guardedKillFound = hasEarlierWriteWithSameGuard(mnd, defines);
1386 
1387  // if no kills to this reg in this BB, this one kills it.
1388  if (currentBB_->basicBlock().liveRangeData_->regKills_.find(reg) ==
1390 
1391  // is this alone a kill?
1392  if (mnd.mn()->move().isUnconditional()) {
1393  currentBB_->basicBlock().liveRangeData_->regKills_[reg].first = mnd;
1395  } else {
1396  // two guarded moves with opposite guards together may be a kill.
1397  // Check if we have such previous guarded write with opposite
1398  // guard.
1399  std::map<TCEString, std::pair<MoveNodeUse, bool> >::iterator
1400  iter =
1402  if (iter != currentBB_->basicBlock().liveRangeData_->potentialRegKills_.end() &&
1404  *(iter->second.first.mn()), *(mnd.mn()))) {
1406  iter->second.first;
1407  currentBB_->basicBlock().liveRangeData_->regKills_[reg].second = mnd;
1408  }
1409  }
1410  if (!guardedKillFound) {
1411  // may have incoming WaW's / WaRs to this
1412  // insert to bookkeeping for further analysis.
1414 
1415  // do we need to create some inter-bb-antideps?
1417  // deps from other BB.LIVERANGEDATA_->
1419  mnd, reg, currentBB_->basicBlock());
1420  }
1421  }
1422  }
1423 
1424  // Create antideps to defines and uses in this same BB.LIVERANGEDATA_->
1427  reg, mnd, defines, DataDependenceEdge::DEP_WAW, guardedKillFound);
1428 
1430  reg, mnd, lastUses, DataDependenceEdge::DEP_WAR,
1431  guardedKillFound);
1432  }
1433 
1434  // if unconditional, this kills previous deps.
1435  if (mnd.mn()->move().isUnconditional()) {
1436  defines.clear();
1437 
1438  currentBB_->basicBlock().liveRangeData_->regLastKills_[reg].first = mnd;
1440 
1441  // clear reads to given reg.
1442  lastUses.clear();
1444  } else {
1445  // two guarded moves with opposite guards together may be a kill.
1446  // Check if we have such previous guarded write with opposite
1447  // guard.
1448  std::map<TCEString, std::pair<MoveNodeUse, bool> >::iterator iter =
1450  if (iter != currentBB_->basicBlock().liveRangeData_->potentialRegKills_.end() &&
1452  *(iter->second.first.mn()), *(mnd.mn()))) {
1453 
1454  // found earlier write which is exclusive with this one.
1455  // mark that these two together are a kill.
1457  iter->second.first;
1458  currentBB_->basicBlock().liveRangeData_->regLastKills_[reg].second = mnd;
1459 
1460  // If we have no usage of the register between these two
1461  // writes forming the kill pair, we can clear our bookkeeping.
1462 
1463  // only leave the other part of the kill to defines.
1464  defines.clear();
1465  defines.insert(iter->second.first);
1466 
1467  if (!iter->second.second) {
1468  // clear reads to given reg.
1469  lastUses.clear();
1470  }
1471  }
1473  std::pair<MoveNodeUse, bool>(mnd, false);
1474  }
1475  defines.insert(mnd);
1476 }

References BasicBlockNode::basicBlock(), createRegisterAntideps(), currentBB_, currentDDG_, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, DataDependenceGraph::exclusingGuards(), hasEarlierWriteWithSameGuard(), DataDependenceGraph::hasIntraBBRegisterAntidependencies(), DataDependenceGraph::hasSingleBBLoopRegisterAntidependencies(), TTAProgram::Move::isUnconditional(), TTAProgram::BasicBlock::liveRangeData_, MoveNodeUse::mn(), MoveNode::move(), LiveRangeData::potentialRegKills_, LiveRangeData::regDefines_, LiveRangeData::regFirstDefines_, LiveRangeData::regKills_, LiveRangeData::regLastKills_, LiveRangeData::regLastUses_, and DataDependenceGraph::updateRegWrite().

Referenced by processCall(), and processDestination().

Here is the call graph for this function:

◆ processResultRead()

void DataDependenceGraphBuilder::processResultRead ( MoveNode moveNode)
protected

Analyzes a source of a result read.

Handles program operation creation and operation dependence creation.

Parameters
moveNodeMoveNode of the move being analyzed.

Definition at line 1104 of file DataDependenceGraphBuilder.cc.

1104  {
1105 
1106  // Goes thru all programoperations lacking result read.
1107  // There should be only one if well-behaving
1108  // universalmachine code.
1109  if (currentData_->readPending_ != NULL) {
1112 
1113  if (!po->isComplete()) {
1114  po->addOutputNode(moveNode);
1115  moveNode.setSourceOperationPtr(po);
1116  }
1117 
1118  // if this PO is ready, remove from list of incomplete ones
1119  if (currentData_->poReadsHandled_ >=
1120  po->operation().numberOfOutputs()) {
1125  }
1126  return;
1127  }
1128  throw IllegalProgram(
1129  __FILE__, __LINE__, __func__,
1130  (boost::format("Result move '%s' without operands") %
1131  moveNode.move().toString()).str());
1132 }

References __func__, DataDependenceGraph::addProgramOperation(), createOperationEdges(), currentData_, currentDDG_, MoveNode::move(), DataDependenceGraphBuilder::BBData::poReadsHandled_, DataDependenceGraphBuilder::BBData::readPending_, MoveNode::setSourceOperationPtr(), and TTAProgram::Move::toString().

Referenced by processSource().

Here is the call graph for this function:

◆ processReturn()

void DataDependenceGraphBuilder::processReturn ( MoveNode moveNode)
protected

Processes a return from a function.

Creates pseudo-read-deps to SP and RV registers.

Parameters
moveNodemoveNode containg the return move.

Definition at line 1486 of file DataDependenceGraphBuilder.cc.

1486  {
1488 
1489  // return is considered as read of sp;
1490  // sp must be correct at the end of the procedure.
1491  if (sp != "") {
1492  processRegUse(MoveNodeUse(moveNode,false,false,true),sp);
1493  }
1494 
1495  // return is considered as read of RV.
1497  if (rv != "") {
1498  processRegUse(MoveNodeUse(moveNode,false,false,true),rv);
1499  }
1500 
1501  // process all vector rv values
1502  for (int i = REG_VRV;;i--) {
1503  auto vrvIt = specialRegisters_.find(i);
1504  if (vrvIt != specialRegisters_.end()) {
1505  processRegUse(
1506  MoveNodeUse(moveNode,false,false,true),vrvIt->second);
1507  } else {
1508  break;
1509  }
1510  }
1511 
1512  // return is also considered as read of RV high(for 64-bit RV's)
1514  if (rvh != "") {
1515  processRegUse(MoveNodeUse(moveNode,false,false,true),rvh);
1516  }
1517 
1519  if (fp != "") {
1520  processRegUse(MoveNodeUse(moveNode,false,false,true),fp);
1521  }
1522 }

References processRegUse(), REG_FP, REG_RV, REG_RV_HIGH, REG_SP, REG_VRV, and specialRegisters_.

Referenced by processSource().

Here is the call graph for this function:

◆ processSource()

void DataDependenceGraphBuilder::processSource ( MoveNode moveNode)
protected

Analysis a source of a move and processes it's dependencies, and if it's a result read then also participates in ProgramOperation creation.

Parameters
moveNodeMovenode being analyzed.

Definition at line 785 of file DataDependenceGraphBuilder.cc.

785  {
786  Terminal& source = moveNode.move().source();
787 
788  // is this result move of an operation?
789  if (source.isFUPort()) {
790  if (!(dynamic_cast<const SpecialRegisterPort*>(&source.port()))) {
791  processResultRead(moveNode);
792  } else {
793  // handle read from RA.
794  processRegUse(MoveNodeUse(moveNode, false, true), RA_NAME);
795 
796  if (moveNode.move().isReturn()) {
797  processReturn(moveNode);
798  }
799  }
800  } else {
801  if (source.isGPR()) {
802  TerminalRegister& tr = dynamic_cast<TerminalRegister&>(source);
804  processRegUse(MoveNodeUse(moveNode), regName);
805  }
806  }
807 }

References TTAProgram::Terminal::isFUPort(), TTAProgram::Terminal::isGPR(), TTAProgram::Move::isReturn(), MoveNode::move(), TTAProgram::Terminal::port(), processRegUse(), processResultRead(), processReturn(), RA_NAME, DisassemblyRegister::registerName(), and TTAProgram::Move::source().

Referenced by constructIndividualBB().

Here is the call graph for this function:

◆ processTriggerMemoryAndFUStates()

void DataDependenceGraphBuilder::processTriggerMemoryAndFUStates ( MoveNode moveNode,
Operation dop 
)
protected

Analyze write to a trigger of an operation.

Participates in ProgramOperation building. Calls createTriggerDependencies(moveNode, dop) to create the memory and fu state dependence egdes of the operation. Checks if operation is call and if it is, processes the call-related memory dependencies.

Parameters
moveNodemnData related to a move which triggers an operation
dopOperation being triggered

Definition at line 1040 of file DataDependenceGraphBuilder.cc.

1041  {
1042 
1043  createTriggerDependencies(moveNode, dop);
1044 
1045  // handle call mem deps
1046  if (moveNode.move().isFunctionCall()) {
1047  // no guard, is not ra, is pseudo.
1048  MoveNodeUse mnd2(moveNode, false, false, true);
1049  processMemWrite(mnd2);
1050  }
1051 }

References createTriggerDependencies(), TTAProgram::Move::isFunctionCall(), MoveNode::move(), and processMemWrite().

Referenced by processDestination().

Here is the call graph for this function:

◆ processTriggerPO()

void DataDependenceGraphBuilder::processTriggerPO ( class MoveNode moveNode,
Operation dop 
)
protected

Handles ProgramOperation creation for a triggering move.

Parameters
moveNodetriggering movenode.
dopoperation which is being triggered by the movenode.

Definition at line 948 of file DataDependenceGraphBuilder.cc.

949  {
950  if (currentData_->destPending_ != NULL) {
952 
953  if (&dop != &po->operation()) {
954  std::cerr << "pending po: " << po->toString() << std::endl;
955  std::cerr << "current dop: " << dop.name() << std::endl;
956  currentDDG_->writeToDotFile("build_fail_po.dot");
957  }
958  assert(&dop == &po->operation());
959  if (!po->isComplete()) {
960  po->addInputNode(moveNode);
961  moveNode.addDestinationOperationPtr(po);
962  }
963  if (po->isReady()) {
965  if (dop.numberOfOutputs() > 0) {
966  assert(currentData_->readPending_ == NULL);
969  } else {
971  }
972  } else {
973  throw IllegalProgram(
974  __FILE__, __LINE__, __func__,
975  "Trigger before all operands.");
976  }
977  return;
978  }
979  // only one triggering input?
980  if (dop.numberOfInputs() == 1) {
981  TerminalFUPort& tfpd =
982  dynamic_cast<TerminalFUPort&>(moveNode.move().destination());
984  if (tfpd.hasProgramOperation()) {
985  po = tfpd.programOperation();
986  } else {
987  po = ProgramOperationPtr(new ProgramOperation(dop));
988  moveNode.addDestinationOperationPtr(po);
989  po->addInputNode(moveNode);
990  }
991  if (dop.numberOfOutputs()) {
992  assert(currentData_->readPending_ == NULL);
994  } else {
996  }
997  } else { // trigger came too early
998  const TCEString moveDisasm =
999  POMDisassembler::disassemble(moveNode.move());
1000  throw IllegalProgram(
1001  __FILE__,__LINE__, __func__,
1002  TCEString("Trigger without operand in ") + moveDisasm);
1003  }
1004 }

References __func__, MoveNode::addDestinationOperationPtr(), DataDependenceGraph::addProgramOperation(), assert, currentData_, currentDDG_, TTAProgram::Move::destination(), DataDependenceGraphBuilder::BBData::destPending_, POMDisassembler::disassemble(), TTAProgram::TerminalFUPort::hasProgramOperation(), MoveNode::move(), Operation::name(), Operation::numberOfInputs(), Operation::numberOfOutputs(), DataDependenceGraphBuilder::BBData::poReadsHandled_, TTAProgram::TerminalFUPort::programOperation(), DataDependenceGraphBuilder::BBData::readPending_, and GraphBase< GraphNode, GraphEdge >::writeToDotFile().

Referenced by processTriggerRegistersAndOperations().

Here is the call graph for this function:

◆ processTriggerRegistersAndOperations()

void DataDependenceGraphBuilder::processTriggerRegistersAndOperations ( MoveNode moveNode,
Operation dop 
)
protected

Analyze write to a trigger of an operation.

Participates in ProgramOperation building. Calls createTriggerDependencies(moveNode, dop) to create the register and operation dependence egdes of the operation. Checks if operation is call and if it is, processes the call-related register dependencies.

Parameters
moveNodemnData related to a move which triggers an operation
dopOperation being triggered

Definition at line 1018 of file DataDependenceGraphBuilder.cc.

1019  {
1020 
1021  processTriggerPO(moveNode, dop);
1022 
1023  if (moveNode.move().isFunctionCall()) {
1024  processCall(moveNode);
1025  }
1026 }

References TTAProgram::Move::isFunctionCall(), MoveNode::move(), processCall(), and processTriggerPO().

Referenced by processDestination().

Here is the call graph for this function:

◆ queueFirstBB()

BasicBlockNode * DataDependenceGraphBuilder::queueFirstBB ( )
protected

Queues first basic block to be processed.

Returns
the first basic block node

Definition at line 2238 of file DataDependenceGraphBuilder.cc.

2238  {
2239  // get first BB where to start
2241  assert(firstBBs.size() == 1);
2242  BasicBlockNode* firstBB = *firstBBs.begin();
2243  changeState(*(bbData_[firstBB]), BB_QUEUED);
2244  return firstBB;
2245 }

References assert, BB_QUEUED, bbData_, cfg_, changeState(), ControlFlowGraph::entryNode(), and BoostGraph< GraphNode, GraphEdge >::successors().

Referenced by createMemAndFUstateDeps(), and createRegisterDeps().

Here is the call graph for this function:

◆ searchRegisterDeaths()

void DataDependenceGraphBuilder::searchRegisterDeaths ( )
protected

Searches the last usages a registers.

This information is used for checking whether given register contains live value at given cycle.

Definition at line 2882 of file DataDependenceGraphBuilder.cc.

2882  {
2883 
2884  // initializes states of all BB's to unreached.
2886 
2887  // start from end of cfg. (sink nodes), queue them
2889  for (ControlFlowGraph::NodeSet::iterator iter =
2890  lastBBs.begin(); iter != lastBBs.end(); iter++) {
2891  changeState(*(bbData_[*iter]), BB_QUEUED);
2892  }
2893 
2894  // then iterate over all BB's, going from BB to it's
2895  // predecessors.
2897 
2898  // all should have gone thru, but if there are 4ever loop causing
2899  // BB's not reachable from the end.
2900  // we might want to handle those also.
2901  while (!blocksByState_[BB_UNREACHED].empty()) {
2903  Application::logStream() << "Warning: BB in 4ever loop!"
2904  << std::endl;
2905  Application::logStream() << "In procedure: " << cfg_->name() <<
2906  std::endl;
2907 // cfg.writeToDotFile("4everloop_bb.dot");
2908  }
2910 
2912  }
2913 
2914  // free bb data
2916 }

References BB_QUEUED, BB_UNREACHED, bbData_, blocksByState_, cfg_, changeState(), AssocTools::deleteAllValues(), initializeBBStates(), iterateRegisterDeaths(), Application::logStream(), BoostGraph< GraphNode, GraphEdge >::name(), BoostGraph< GraphNode, GraphEdge >::sinkNodes(), Application::VERBOSE_LEVEL_DEFAULT, and Application::verboseLevel().

Referenced by build().

Here is the call graph for this function:

◆ setSucceedingPredeps()

void DataDependenceGraphBuilder::setSucceedingPredeps ( BBData bbd,
bool  queueAll,
ConstructionPhase  phase 
)
protected

Sets outgoing data from this BB to incoming data of successors.

Also queues them to be reprocessed if they are changed.

Parameters
bbdBBD whose successors will be updated.
queueAllIf true, queues all successors even if they do not change.
phasewhether to handle register& operation deps or memory and side-effect dependencies.

Definition at line 2424 of file DataDependenceGraphBuilder.cc.

2426  {
2427  BasicBlockNode& bbn = *bbd.bblock_;
2428  BasicBlock& bb = bbn.basicBlock();
2429 
2430  BasicBlockNodeSet forwardSuccessors = cfg_->successors(bbn, true);
2431  for (BasicBlockNodeSet::iterator succIter = forwardSuccessors.begin();
2432  succIter != forwardSuccessors.end(); succIter++) {
2434  bb, **succIter, queueAll, false, phase);
2435  }
2436 
2437  // successors over loop edges.
2438  BasicBlockNodeSet backwardSuccessors = cfg_->successors(bbn, false, true);
2439  for (BasicBlockNodeSet::iterator succIter = backwardSuccessors.begin();
2440  succIter != backwardSuccessors.end(); succIter++) {
2442  bb, **succIter, queueAll, true, phase);
2443  }
2444 }

References BasicBlockNode::basicBlock(), DataDependenceGraphBuilder::BBData::bblock_, cfg_, setSucceedingPredepsForBB(), and BoostGraph< GraphNode, GraphEdge >::successors().

Referenced by iterateBBs().

Here is the call graph for this function:

◆ setSucceedingPredepsForBB()

void DataDependenceGraphBuilder::setSucceedingPredepsForBB ( TTAProgram::BasicBlock processedBB,
BasicBlockNode successor,
bool  queueAll,
bool  loop,
ConstructionPhase  phase 
)
protected

Sets outgoing data from this BB to incoming data of one successor.

Also queues them to be reprocessed if they are changed.

Parameters
bbBB whose successor will be updated.
successorsuccessor BB whose incoming data is being updated.
queueAllIf true, queues all successors even if they do not change.
loopwhether to add loop property to the copied bookkeeping, ie create edges with loop property.
phasewhether to handle register& operation deps or memory and side-effect dependencies.

Definition at line 2460 of file DataDependenceGraphBuilder.cc.

2462  {
2463 
2464  BasicBlock& succBB = successor.basicBlock();
2465  BBData& succData = *bbData_[&successor];
2466  bool changed = false;
2467 
2468  if (phase == REGISTERS_AND_PROGRAM_OPERATIONS) {
2470  bb.liveRangeData_->regDefAfter_,
2471  succBB.liveRangeData_->regDefReaches_, loop);
2472 
2474  (&bb == &succBB &&
2477  bb.liveRangeData_->regUseAfter_,
2478  succBB.liveRangeData_->regUseReaches_, loop);
2479  }
2480  } else {
2481  // mem deps + fu state deps
2482 
2484  bb.liveRangeData_->memDefAfter_,
2485  succBB.liveRangeData_->memDefReaches_, loop);
2486 
2488  bb.liveRangeData_->memUseAfter_,
2489  succBB.liveRangeData_->memUseReaches_, loop);
2490 
2491  size_t size = succBB.liveRangeData_->fuDepReaches_.size();
2493  bb.liveRangeData_->fuDepAfter_,
2494  succBB.liveRangeData_->fuDepReaches_, loop);
2495  if (succBB.liveRangeData_->fuDepReaches_.size() > size) {
2496  changed = true;
2497  }
2498  }
2499 
2500  // need to queue successor for update?
2501  if (changed || queueAll) {
2502  changeState(succData, BB_QUEUED, loop);
2503  }
2504 }

References LiveRangeData::appendMoveNodeUse(), LiveRangeData::appendUseMapSets(), BasicBlockNode::basicBlock(), BB_QUEUED, bbData_, changeState(), currentDDG_, LiveRangeData::fuDepAfter_, LiveRangeData::fuDepReaches_, DataDependenceGraph::hasAllRegisterAntidependencies(), DataDependenceGraph::hasSingleBBLoopRegisterAntidependencies(), TTAProgram::BasicBlock::liveRangeData_, LiveRangeData::memDefAfter_, LiveRangeData::memDefReaches_, LiveRangeData::memUseAfter_, LiveRangeData::memUseReaches_, LiveRangeData::regDefAfter_, LiveRangeData::regDefReaches_, REGISTERS_AND_PROGRAM_OPERATIONS, LiveRangeData::regUseAfter_, and LiveRangeData::regUseReaches_.

Referenced by setSucceedingPredeps().

Here is the call graph for this function:

◆ updateBB()

void DataDependenceGraphBuilder::updateBB ( BBData bbd,
ConstructionPhase  phase 
)
protected

Reprocesses a basic block which has already once been processed.

Checks dependencies to first uses and definitions of registers, does not recreate edges inside the basic block.

Parameters
bbdBBData for basic block which is being reprocessed.
phasewhether to handle register& operation deps or memory and side-effect dependencies.

Definition at line 2743 of file DataDependenceGraphBuilder.cc.

2744  {
2745  currentData_ = &bbd;
2746  currentBB_ = bbd.bblock_;
2747  BasicBlock& bb = bbd.bblock_->basicBlock();
2748 
2749  // register and operation dependencies
2750  if (phase == REGISTERS_AND_PROGRAM_OPERATIONS) {
2751  //loop all regs having ext deps and create reg edges
2752  for (MoveNodeUseMapSet::iterator firstUseIter =
2753  bb.liveRangeData_->regFirstUses_.begin();
2754  firstUseIter != bb.liveRangeData_->regFirstUses_.end();
2755  firstUseIter++) {
2756  TCEString reg = firstUseIter->first;
2757  std::set<MoveNodeUse>& firstUseSet = firstUseIter->second;
2758  for (std::set<MoveNodeUse>::iterator iter2 = firstUseSet.begin();
2759  iter2 != firstUseSet.end(); iter2++) {
2761  *iter2, reg, currentBB_->basicBlock());
2762  }
2763  }
2764 
2766  // antidependencies to registers
2767  for (MoveNodeUseMapSet::iterator firstDefineIter =
2768  bb.liveRangeData_->regFirstDefines_.begin();
2769  firstDefineIter != bb.liveRangeData_->regFirstDefines_.end();
2770  firstDefineIter++) {
2771  TCEString reg = firstDefineIter->first;
2772  std::set<MoveNodeUse>& firstDefineSet =
2773  firstDefineIter->second;
2774  for (std::set<MoveNodeUse>::iterator iter2=
2775  firstDefineSet.begin();
2776  iter2 != firstDefineSet.end(); iter2++) {
2778  *iter2, reg, currentBB_->basicBlock());
2779  }
2780  }
2781  }
2782  } else {
2783  // phase 1 .. mem deps and fu state/side effect dependencies.
2784 
2785  //loop all first mem uses having ext deps and create mem edges
2786  for (MoveNodeUseMapSet::iterator firstUseIter =
2787  bb.liveRangeData_->memFirstUses_.begin();
2788  firstUseIter != bb.liveRangeData_->memFirstUses_.end();
2789  firstUseIter++) {
2790  TCEString category = firstUseIter->first;
2791  std::set<MoveNodeUse>& firstUseSet = firstUseIter->second;
2792  for (std::set<MoveNodeUse>::iterator iter2 = firstUseSet.begin();
2793  iter2 != firstUseSet.end(); iter2++) {
2794  updateMemUse(*iter2, category);
2795  }
2796  }
2797 
2798  // antidependencies to memory
2799  for (MoveNodeUseMapSet::iterator firstDefineIter =
2800  bb.liveRangeData_->memFirstDefines_.begin();
2801  firstDefineIter != bb.liveRangeData_->memFirstDefines_.end();
2802  firstDefineIter++) {
2803  TCEString category = firstDefineIter->first;
2804  std::set<MoveNodeUse>& firstDefineSet = firstDefineIter->second;
2805  for (std::set<MoveNodeUse>::iterator iter2=firstDefineSet.begin();
2806  iter2 != firstDefineSet.end(); iter2++) {
2807  updateMemWrite(*iter2, category);
2808  }
2809  }
2810 
2811  // and fu state deps
2812  for (MoveNodeUseSet::iterator iter =
2813  bb.liveRangeData_->fuDeps_.begin();
2814  iter != bb.liveRangeData_->fuDeps_.end(); iter++) {
2815  Terminal& dest = iter->mn()->move().destination();
2816  TerminalFUPort& tfpd = dynamic_cast<TerminalFUPort&>(dest);
2817  Operation &dop = tfpd.hintOperation();
2820  *iter->mn(), dop);
2821  }
2822  }
2823 }

References BasicBlockNode::basicBlock(), DataDependenceGraphBuilder::BBData::bblock_, createSideEffectEdges(), currentBB_, currentData_, currentDDG_, LiveRangeData::fuDepReaches_, LiveRangeData::fuDeps_, DataDependenceGraph::hasSingleBBLoopRegisterAntidependencies(), TTAProgram::TerminalFUPort::hintOperation(), TTAProgram::BasicBlock::liveRangeData_, LiveRangeData::memFirstDefines_, LiveRangeData::memFirstUses_, LiveRangeData::regFirstDefines_, LiveRangeData::regFirstUses_, REGISTERS_AND_PROGRAM_OPERATIONS, updateMemUse(), updateMemWrite(), DataDependenceGraph::updateRegUse(), and DataDependenceGraph::updateRegWrite().

Referenced by iterateBBs().

Here is the call graph for this function:

◆ updateMemAndFuAliveAfter()

bool DataDependenceGraphBuilder::updateMemAndFuAliveAfter ( BBData bbd)
protected

Updates live mem access lists and fu state usages after a basic block has been processed.

Copies use and write definitions from the basic block and it's prodecessors to the after alive data structures.

Parameters
bbdBBData for bb being processed
Returns
true if the after alive data structures have been changed

Definition at line 2592 of file DataDependenceGraphBuilder.cc.

2592  {
2593  BasicBlock& bb = bbd.bblock_->basicBlock();
2594  bool changed = false;
2595 
2596  // copy mem definitions that are alive
2597  for (MoveNodeUseMapSet::iterator iter = bb.liveRangeData_->memDefReaches_.begin();
2598  iter != bb.liveRangeData_->memDefReaches_.end(); iter++) {
2599 
2600  TCEString category = iter->first;
2601  std::set<MoveNodeUse>& preDefs = iter->second;
2602  std::set<MoveNodeUse>& defAfter = bb.liveRangeData_->memDefAfter_[category];
2603  std::set<MoveNodeUse>& ownDefines = bb.liveRangeData_->memDefines_[category];
2604  size_t size = defAfter.size();
2605 
2606  // only copy incomin dep if this has no unconditional writes,
2607  if (bb.liveRangeData_->memKills_.find(category) == bb.liveRangeData_->memKills_.end()) {
2608  for (std::set<MoveNodeUse>::iterator i = preDefs.begin();
2609  i != preDefs.end(); i++ ) {
2610 // MoveNode* preAddress = addressMove(*(i->mn()));
2611  ProgramOperation& prevPop = i->mn()->destinationOperation();
2612 
2613  bool overWritten = false;
2614  for (std::set<MoveNodeUse>::iterator j = ownDefines.begin();
2615  j != ownDefines.end(); j++) {
2616  if (j->mn()->move().isUnconditional()) {
2617 // MoveNode* ownAddress = addressMove(*(j->mn()));
2618  ProgramOperation& ownPop = j->mn()->destinationOperation();
2619  if (analyzeMemoryAlias(prevPop, ownPop, i->bbRelation()) ==
2621  overWritten = true;
2622  break;
2623  }
2624  }
2625  }
2626  if (!overWritten) {
2627  defAfter.insert(*i);
2628  }
2629  }
2630  }
2631  // if size increased, the data has changed
2632  if (size < defAfter.size()) {
2633  changed = true;
2634  }
2635  }
2636  // own deps. need to do only once but now does after every.
2639  bb.liveRangeData_->memDefAfter_, false);
2640 
2641  // copy uses that are alive
2642  for (MoveNodeUseMapSet::iterator iter = bb.liveRangeData_->memUseReaches_.begin();
2643  iter != bb.liveRangeData_->memUseReaches_.end(); iter++) {
2644 
2645  TCEString category = iter->first;
2646  std::set<MoveNodeUse>& preUses = iter->second;
2647  std::set<MoveNodeUse>& useAfter = bb.liveRangeData_->memUseAfter_[category];
2648  std::set<MoveNodeUse>& ownDefines = bb.liveRangeData_->memDefines_[category];
2649 
2650  size_t size = useAfter.size();
2651  if (bb.liveRangeData_->memKills_.find(category) == bb.liveRangeData_->memKills_.end()) {
2652  for (std::set<MoveNodeUse>::iterator i = preUses.begin();
2653  i != preUses.end(); i++ ) {
2654 // MoveNode* preAddress = addressMove(*(i->mn()));
2655  ProgramOperation& prevPop = i->mn()->destinationOperation();
2656  bool overWritten = false;
2657  for (std::set<MoveNodeUse>::iterator j =
2658  ownDefines.begin(); j != ownDefines.end(); j++) {
2659  if (j->mn()->move().isUnconditional()) {
2660  ProgramOperation& ownPop = j->mn()->destinationOperation();
2661  if (analyzeMemoryAlias(prevPop, ownPop, i->bbRelation()) ==
2663  overWritten = true;
2664  break;
2665  }
2666  }
2667  }
2668  if (!overWritten) {
2669  useAfter.insert(*i);
2670  }
2671  }
2672  }
2673  // if size increased, the data has changed
2674  if (size < useAfter.size()) {
2675  changed = true;
2676  }
2677  }
2678 
2679  // fu deps
2680  size_t size = bb.liveRangeData_->fuDepAfter_.size();
2682  if (bb.liveRangeData_->fuDepAfter_.size() > size) {
2683  changed = true;
2684  }
2685  return changed;
2686 }

References MemoryAliasAnalyzer::ALIAS_TRUE, analyzeMemoryAlias(), AssocTools::append(), LiveRangeData::appendUseMapSets(), BasicBlockNode::basicBlock(), DataDependenceGraphBuilder::BBData::bblock_, LiveRangeData::fuDepAfter_, LiveRangeData::fuDeps_, TTAProgram::BasicBlock::liveRangeData_, LiveRangeData::memDefAfter_, LiveRangeData::memDefines_, LiveRangeData::memDefReaches_, LiveRangeData::memKills_, LiveRangeData::memUseAfter_, and LiveRangeData::memUseReaches_.

Referenced by iterateBBs().

Here is the call graph for this function:

◆ updateMemUse()

void DataDependenceGraphBuilder::updateMemUse ( MoveNodeUse  mnd,
const TCEString category 
)
protected

Checks memory read against uses and defs in incoming basic blocks. Creates the needed dependence edges.

Parameters
mndMoveNodeUse of movenode being processed.
categorywhich memory category this memory write belongs.

Definition at line 2859 of file DataDependenceGraphBuilder.cc.

2860  {
2861 
2862  for (MoveNodeUseSet::iterator iter =
2863  currentBB_->basicBlock().liveRangeData_->memDefReaches_[category].begin();
2864  iter != currentBB_->basicBlock().liveRangeData_->memDefReaches_[category].end();
2865  iter++) {
2867  }
2868 }

References BasicBlockNode::basicBlock(), checkAndCreateMemDep(), currentBB_, DataDependenceEdge::DEP_RAW, TTAProgram::BasicBlock::liveRangeData_, and LiveRangeData::memDefReaches_.

Referenced by processMemUse(), and updateBB().

Here is the call graph for this function:

◆ updateMemWrite()

void DataDependenceGraphBuilder::updateMemWrite ( MoveNodeUse  mnd,
const TCEString category 
)
protected

Checks memory write against uses and defs in incoming basic blocks. Creates the needed dependence edges.

Parameters
mndMoveNodeUse of movenode being processed.
categorywhich memory category this memory write belongs.

Definition at line 2833 of file DataDependenceGraphBuilder.cc.

2834  {
2835 
2836  // create waw edges from all alive writes to this node.
2837  for (MoveNodeUseSet::iterator iter =
2838  currentBB_->basicBlock().liveRangeData_->memDefReaches_[category].begin();
2839  iter != currentBB_->basicBlock().liveRangeData_->memDefReaches_[category].end();) {
2841  }
2842 
2843  // create war edges from all alive reads to this node.
2844  for (MoveNodeUseSet::iterator iter = currentBB_->basicBlock().liveRangeData_->
2845  memUseReaches_[category].begin();
2846  iter != currentBB_->basicBlock().liveRangeData_->memUseReaches_[category].end();) {
2848  }
2849 }

References BasicBlockNode::basicBlock(), checkAndCreateMemDep(), currentBB_, DataDependenceEdge::DEP_WAR, DataDependenceEdge::DEP_WAW, TTAProgram::BasicBlock::liveRangeData_, LiveRangeData::memDefReaches_, and LiveRangeData::memUseReaches_.

Referenced by processMemWrite(), and updateBB().

Here is the call graph for this function:

◆ updatePreceedingRegistersUsedAfter()

void DataDependenceGraphBuilder::updatePreceedingRegistersUsedAfter ( BBData bbd,
bool  firstTime 
)
protected

Updates bookkeeping used for calculating register deaths.

Marks registers used at or after some BB to it's predecessor BB's.

Parameters
bbdbasic block to process.
firstTimewhether this BB is analyzer for the first time.

Definition at line 2390 of file DataDependenceGraphBuilder.cc.

2391  {
2392  BasicBlockNode& bbn = *bbd.bblock_;
2393  BasicBlock& bb = bbn.basicBlock();
2394  BasicBlockNodeSet predecessors = cfg_->predecessors(bbn);
2395  for (BasicBlockNodeSet::iterator predIter = predecessors.begin();
2396  predIter != predecessors.end(); predIter++) {
2397  BasicBlockNode* pred = *predIter;
2398  BasicBlock& predBB = pred->basicBlock();
2399  BBData& predData = *bbData_[pred];
2400  size_t size = predBB.liveRangeData_->registersUsedAfter_.size();
2403 
2404  // if updated, need to be handled again.
2405  if (predBB.liveRangeData_->registersUsedAfter_.size() > size || firstTime) {
2406  if (predData.state_ != BB_QUEUED) {
2407  changeState(predData, BB_QUEUED);
2408  }
2409  }
2410  }
2411 }

References AssocTools::append(), BasicBlockNode::basicBlock(), BB_QUEUED, bbData_, DataDependenceGraphBuilder::BBData::bblock_, cfg_, changeState(), TTAProgram::BasicBlock::liveRangeData_, BoostGraph< GraphNode, GraphEdge >::predecessors(), LiveRangeData::registersUsedAfter_, LiveRangeData::registersUsedInOrAfter_, and DataDependenceGraphBuilder::BBData::state_.

Referenced by iterateRegisterDeaths().

Here is the call graph for this function:

◆ updateRegistersAliveAfter()

bool DataDependenceGraphBuilder::updateRegistersAliveAfter ( BBData bbd)
protected

Updates live register lists after a basic block has been processed.

Copies use and define definitions from the basic block and it's prodecessors to the after alive data structures.

Parameters
bbdBBData for bb being processed
Returns
true if the after alive data structures have been changed

Definition at line 2519 of file DataDependenceGraphBuilder.cc.

2520  {
2521  BasicBlock& bb = bbd.bblock_->basicBlock();
2522  bool changed = false;
2523 
2524  // copy reg definitions that are alive
2525  for (MoveNodeUseMapSet::iterator iter =
2526  bb.liveRangeData_->regDefReaches_.begin();
2527  iter != bb.liveRangeData_->regDefReaches_.end(); iter++) {
2528 
2529  TCEString reg = iter->first;
2530  std::set<MoveNodeUse>& preDefs = iter->second;
2531  // todo: clear or not?
2532  std::set<MoveNodeUse>& defAfter = bb.liveRangeData_->regDefAfter_[reg];
2533  size_t size = defAfter.size();
2534 
2535  // only copy incomin dep if this has no unconditional writes
2536  if (bb.liveRangeData_->regKills_.find(reg) == bb.liveRangeData_->regKills_.end()) {
2537  for (std::set<MoveNodeUse>::iterator i = preDefs.begin();
2538  i != preDefs.end(); i++ ) {
2539  defAfter.insert(*i);
2540  }
2541  }
2542  // if size increased, the data has changed
2543  if (size < defAfter.size()) {
2544  changed = true;
2545  }
2546  }
2547  // own deps. need to do only once but now does after every.
2550  bb.liveRangeData_->regDefAfter_, false);
2551 
2553  // copy uses that are alive
2554  for (MoveNodeUseMapSet::iterator iter =
2555  bb.liveRangeData_->regUseReaches_.begin(); iter != bb.liveRangeData_->regUseReaches_.end();
2556  iter++) {
2557  TCEString reg = iter->first;
2558  std::set<MoveNodeUse>& preUses = iter->second;
2559  std::set<MoveNodeUse>& useAfter = bb.liveRangeData_->regUseAfter_[reg];
2560  size_t size = useAfter.size();
2561  if (bb.liveRangeData_->regKills_.find(reg) == bb.liveRangeData_->regKills_.end()) {
2562  for (std::set<MoveNodeUse>::iterator i = preUses.begin();
2563  i != preUses.end(); i++ ) {
2564  useAfter.insert(*i);
2565  }
2566  }
2567  // if size increased, the data has changed
2568  if (size < useAfter.size()) {
2569  changed = true;
2570  }
2571  }
2572  }
2573 
2574  // own deps. need to do only once but now does after every.
2577  bb.liveRangeData_->regUseAfter_, false);
2578  return changed;
2579 }

References LiveRangeData::appendUseMapSets(), BasicBlockNode::basicBlock(), DataDependenceGraphBuilder::BBData::bblock_, currentDDG_, DataDependenceGraph::hasAllRegisterAntidependencies(), TTAProgram::BasicBlock::liveRangeData_, LiveRangeData::regDefAfter_, LiveRangeData::regDefines_, LiveRangeData::regDefReaches_, LiveRangeData::regKills_, LiveRangeData::regLastUses_, LiveRangeData::regUseAfter_, and LiveRangeData::regUseReaches_.

Referenced by iterateBBs().

Here is the call graph for this function:

◆ updateRegistersUsedInOrAfter()

bool DataDependenceGraphBuilder::updateRegistersUsedInOrAfter ( BBData bbd)
protected

Updates bookkeeping about registers used in this or later BBs.

This is a helper function used by searchRegisterDeaths() method.

Parameters
bbdData about one basicblock.
Returns
whether the bookkeeping was changed, ie the predecessors of this BB need to be reprocessed.

Definition at line 2955 of file DataDependenceGraphBuilder.cc.

2956  {
2957  BasicBlock& bb = bbd.bblock_->basicBlock();
2958  size_t size = bb.liveRangeData_->registersUsedInOrAfter_.size();
2959 
2960  // if definition not here, it's earlier - copy.
2961  // if definition here, not alive unless read here.
2962  for (std::set<TCEString>::iterator i = bb.liveRangeData_->registersUsedAfter_.begin();
2963  i != bb.liveRangeData_->registersUsedAfter_.end(); i++) {
2964  // if not written in this, written earlier.
2965  if (bb.liveRangeData_->regKills_.find(*i) == bb.liveRangeData_->regKills_.end()) {
2966  bb.liveRangeData_->registersUsedInOrAfter_.insert(*i);
2967  }
2968  }
2969 
2970  // reads in this BB.liveRangeData_-> Only reads whose defining value comes/can come
2971  // outside this BB.liveRangeData_->
2972  for (MoveNodeUseMapSet::iterator i = bb.liveRangeData_->regFirstUses_.begin();
2973  i != bb.liveRangeData_->regFirstUses_.end(); i++) {
2974  bb.liveRangeData_->registersUsedInOrAfter_.insert(i->first);
2975  }
2976  if (bb.liveRangeData_->registersUsedInOrAfter_.size() > size) {
2977  return true;
2978  }
2979  return false;
2980 }

References BasicBlockNode::basicBlock(), DataDependenceGraphBuilder::BBData::bblock_, TTAProgram::BasicBlock::liveRangeData_, LiveRangeData::regFirstUses_, LiveRangeData::registersUsedAfter_, LiveRangeData::registersUsedInOrAfter_, and LiveRangeData::regKills_.

Referenced by iterateRegisterDeaths().

Here is the call graph for this function:

Member Data Documentation

◆ aliasAnalyzers_

AliasAnalyzerVector DataDependenceGraphBuilder::aliasAnalyzers_
protected

◆ allParamRegs_

std::set<TCEString> DataDependenceGraphBuilder::allParamRegs_
protected

◆ bbData_

BBDataMap DataDependenceGraphBuilder::bbData_
protected

◆ blocksByState_

BBDataList DataDependenceGraphBuilder::blocksByState_[BB_STATES]
protected

◆ cfg_

ControlFlowGraph* DataDependenceGraphBuilder::cfg_
protected

◆ currentBB_

BasicBlockNode* DataDependenceGraphBuilder::currentBB_
protected

◆ currentData_

BBData* DataDependenceGraphBuilder::currentData_
protected

◆ currentDDG_

DataDependenceGraph* DataDependenceGraphBuilder::currentDDG_
protected

◆ interPassData_

InterPassData* DataDependenceGraphBuilder::interPassData_
protected

Definition at line 319 of file DataDependenceGraphBuilder.hh.

◆ mach_

const TTAMachine::Machine* DataDependenceGraphBuilder::mach_
protected

Definition at line 322 of file DataDependenceGraphBuilder.hh.

Referenced by build(), and isTriggering().

◆ RA_NAME

const TCEString DataDependenceGraphBuilder::RA_NAME = "RA"
staticprotected

Internal constant for the name of the return address port

Definition at line 318 of file DataDependenceGraphBuilder.hh.

Referenced by processCall(), processDestination(), processEntryNode(), and processSource().

◆ rvIsParamReg_

bool DataDependenceGraphBuilder::rvIsParamReg_
protected

◆ specialRegisters_

SpecialRegisters DataDependenceGraphBuilder::specialRegisters_
protected

contains stack pointer, RV and parameter registers.

Definition at line 317 of file DataDependenceGraphBuilder.hh.

Referenced by build(), DataDependenceGraphBuilder(), processCall(), processEntryNode(), and processReturn().


The documentation for this class was generated from the following files:
DataDependenceGraphBuilder::mach_
const TTAMachine::Machine * mach_
Definition: DataDependenceGraphBuilder.hh:322
TTAMachine::Guard
Definition: Guard.hh:55
UniversalMachine::integerRegisterFile
UnboundedRegisterFile & integerRegisterFile() const
Definition: UniversalMachine.cc:234
ProgramOperation::operation
const Operation & operation() const
Definition: ProgramOperation.cc:590
TTAProgram::Terminal::isFUPort
virtual bool isFUPort() const
Definition: Terminal.cc:118
DataDependenceGraphBuilder::BBData::poReadsHandled_
int poReadsHandled_
Definition: DataDependenceGraphBuilder.hh:135
Operation::affectedByCount
virtual int affectedByCount() const
Definition: Operation.cc:416
DataDependenceGraphBuilder::isTriggering
bool isTriggering(const MoveNode &mn)
Definition: DataDependenceGraphBuilder.cc:810
SimpleInterPassDatum
Definition: InterPassDatum.hh:64
LiveRangeData::regLastKills_
MoveNodeUseMapPair regLastKills_
Definition: LiveRangeData.hh:80
BoostGraph::predecessors
virtual NodeSet predecessors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
MemoryAliasAnalyzer::ALIAS_UNKNOWN
@ ALIAS_UNKNOWN
Definition: MemoryAliasAnalyzer.hh:54
ConstantAliasAnalyzer
Definition: ConstantAliasAnalyzer.hh:42
DataDependenceGraphBuilder::BB_STATES
@ BB_STATES
BB which is already processed and is not queued.
Definition: DataDependenceGraphBuilder.hh:118
DataDependenceGraphBuilder::clearUnneededBookkeeping
void clearUnneededBookkeeping()
Definition: DataDependenceGraphBuilder.cc:2251
DataDependenceGraphBuilder::blocksByState_
BBDataList blocksByState_[BB_STATES]
Definition: DataDependenceGraphBuilder.hh:309
Exception::lineNum
int lineNum() const
DataDependenceGraphBuilder::createMemAndFUstateDeps
void createMemAndFUstateDeps()
Definition: DataDependenceGraphBuilder.cc:2312
MoveNodeUse::mn
const MoveNode * mn() const
Definition: MoveNodeUse.hh:39
TTAMachine::Component::name
virtual TCEString name() const
Definition: MachinePart.cc:125
MoveNode::toString
std::string toString() const
Definition: MoveNode.cc:576
LiveRangeData::inlineAsmRegDefs_
std::set< TCEString > inlineAsmRegDefs_
Definition: LiveRangeData.hh:127
Operation::hasSideEffects
virtual bool hasSideEffects() const
Definition: Operation.cc:272
TTAProgram::Instruction::move
Move & move(int i) const
Definition: Instruction.cc:193
PRINT_VAR
#define PRINT_VAR(VARIABLE__)
Definition: Application.hh:118
MemoryAliasAnalyzer::analyze
virtual AliasingResult analyze(DataDependenceGraph &ddg, const ProgramOperation &pop1, const ProgramOperation &pop2, MoveNodeUse::BBRelation bbInfo)=0
TTAProgram::Move::isFunctionCall
bool isFunctionCall() const
Definition: Move.cc:219
DataDependenceGraphBuilder::constructIndividualFromInlineAsmBB
void constructIndividualFromInlineAsmBB(ConstructionPhase phase)
Definition: DataDependenceGraphBuilder.cc:669
DataDependenceGraphBuilder::processResultRead
void processResultRead(MoveNode &moveNode)
Definition: DataDependenceGraphBuilder.cc:1104
BoostGraph::node
Node & node(const int index) const
LiveRangeData::appendMoveNodeUse
static void appendMoveNodeUse(const MoveNodeUseSet &src, MoveNodeUseSet &dst, bool setLoopProperty)
Definition: LiveRangeData.cc:107
TTAMachine::RegisterGuard::registerIndex
int registerIndex() const
LiveRangeData::memFirstUses_
MoveNodeUseMapSet memFirstUses_
Definition: LiveRangeData.hh:104
DataDependenceGraphBuilder::findStaticRegisters
void findStaticRegisters(TTAProgram::CodeSnippet &cs, std::map< int, TCEString > &registers)
find special register data from old frontend code
Definition: DataDependenceGraphBuilder.cc:306
BasicBlockNode::originalEndAddress
InstructionAddress originalEndAddress() const
Definition: BasicBlockNode.cc:174
MoveNode::isDestinationOperation
bool isDestinationOperation() const
DataDependenceGraphBuilder::processCall
void processCall(MoveNode &mn)
Definition: DataDependenceGraphBuilder.cc:1532
TTAProgram::Move::isReturn
bool isReturn() const
Definition: Move.cc:259
MemoryAliasAnalyzer::ALIAS_FALSE
@ ALIAS_FALSE
Definition: MemoryAliasAnalyzer.hh:50
DataDependenceGraph::sameGuards
bool sameGuards(const MoveNode &mn1, const MoveNode &mn2) const
Definition: DataDependenceGraph.cc:4506
LiveRangeData::fuDeps_
MoveNodeUseSet fuDeps_
Definition: LiveRangeData.hh:117
DataDependenceGraphBuilder::processTriggerRegistersAndOperations
void processTriggerRegistersAndOperations(MoveNode &moveNode, Operation &dop)
Definition: DataDependenceGraphBuilder.cc:1018
BoostGraph< BasicBlockNode, ControlFlowEdge >::NodeSet
std::set< BasicBlockNode *, typename BasicBlockNode ::Comparator > NodeSet
Definition: BoostGraph.hh:86
TTAProgram::Instruction
Definition: Instruction.hh:57
TTAProgram::Move::isUnconditional
bool isUnconditional() const
Definition: Move.cc:154
TTAProgram::ProgramAnnotation::stringValue
std::string stringValue() const
Definition: ProgramAnnotation.cc:90
DataDependenceGraphBuilder::initializeBBStates
void initializeBBStates()
Definition: DataDependenceGraphBuilder.cc:2191
MoveNodeUse::pseudo
bool pseudo() const
Definition: MoveNodeUse.hh:42
DataDependenceGraphBuilder::processEntryNode
void processEntryNode(MoveNode &mn)
Definition: DataDependenceGraphBuilder.cc:2694
MoveNodeUse
Definition: MoveNodeUse.hh:20
LiveRangeData::memFirstDefines_
MoveNodeUseMapSet memFirstDefines_
Definition: LiveRangeData.hh:105
DataDependenceGraphBuilder::processMemUse
void processMemUse(MoveNodeUse mnd)
Definition: DataDependenceGraphBuilder.cc:1800
LiveRangeData::inlineAsmClobbers_
std::set< TCEString > inlineAsmClobbers_
Definition: LiveRangeData.hh:128
LiveRangeData::regUseReaches_
MoveNodeUseMapSet regUseReaches_
Definition: LiveRangeData.hh:91
DataDependenceGraph::addProgramOperation
void addProgramOperation(ProgramOperationPtr po)
Definition: DataDependenceGraph.cc:298
DataDependenceGraphBuilder::updateMemUse
void updateMemUse(MoveNodeUse mnd, const TCEString &category)
Definition: DataDependenceGraphBuilder.cc:2859
MemoryAliasAnalyzer::ALIAS_PARTIAL
@ ALIAS_PARTIAL
Definition: MemoryAliasAnalyzer.hh:55
LiveRangeData::memLastUses_
MoveNodeUseMapSet memLastUses_
Definition: LiveRangeData.hh:99
TTAProgram::Move::destination
Terminal & destination() const
Definition: Move.cc:323
LiveRangeData::regDefines_
MoveNodeUseMapSet regDefines_
Definition: LiveRangeData.hh:78
Operation::dependsOn
virtual bool dependsOn(const Operation &op) const
Definition: Operation.cc:458
Application::VERBOSE_LEVEL_DEFAULT
static const int VERBOSE_LEVEL_DEFAULT
Default verbose level - do not print anything unnecessary.
Definition: Application.hh:222
DataDependenceGraphBuilder::aliasAnalyzers_
AliasAnalyzerVector aliasAnalyzers_
Definition: DataDependenceGraphBuilder.hh:315
Operation::numberOfInputs
virtual int numberOfInputs() const
Definition: Operation.cc:192
ProgramOperation
Definition: ProgramOperation.hh:70
DataDependenceGraph::setMachine
void setMachine(const TTAMachine::Machine &machine)
Definition: DataDependenceGraph.cc:3116
TTAProgram::Move::toString
std::string toString() const
Definition: Move.cc:436
DataDependenceGraphBuilder::createSideEffectEdges
void createSideEffectEdges(MoveNodeUseSet &prevMoves, const MoveNode &mn, Operation &dop)
Definition: DataDependenceGraphBuilder.cc:1646
MoveNode
Definition: MoveNode.hh:65
DataDependenceGraphBuilder::processMemWrite
void processMemWrite(MoveNodeUse mnd)
Definition: DataDependenceGraphBuilder.cc:1744
ProgramOperation::machineInstr
const llvm::MachineInstr * machineInstr() const
Definition: ProgramOperation.hh:136
LiveRangeData::regKills_
MoveNodeUseMapPair regKills_
Definition: LiveRangeData.hh:85
DataDependenceGraphBuilder::earlierWritesWithSameGuard
std::set< MoveNodeUse > earlierWritesWithSameGuard(MoveNodeUse &mnd, std::set< MoveNodeUse > &defines)
Definition: DataDependenceGraphBuilder.cc:1200
CompileError
Definition: Exception.hh:1019
Application::verboseLevel
static int verboseLevel()
Definition: Application.hh:176
DataDependenceGraphBuilder::BB_UNREACHED
@ BB_UNREACHED
Definition: DataDependenceGraphBuilder.hh:115
DataDependenceGraphBuilder::currentBB_
BasicBlockNode * currentBB_
Definition: DataDependenceGraphBuilder.hh:312
LLVMAliasAnalyzer
Definition: LLVMAliasAnalyzer.hh:54
DataDependenceEdge::EDGE_REGISTER
@ EDGE_REGISTER
Definition: DataDependenceEdge.hh:53
Application::logStream
static std::ostream & logStream()
Definition: Application.cc:155
DataDependenceGraphBuilder::processGuard
void processGuard(MoveNode &moveNode)
Definition: DataDependenceGraphBuilder.cc:760
BasicBlockNode::isScheduled
bool isScheduled() const
Definition: BasicBlockNode.hh:93
DataDependenceGraphBuilder::queueFirstBB
BasicBlockNode * queueFirstBB()
Definition: DataDependenceGraphBuilder.cc:2238
LLVMTCECmdLineOptions::disableLLVMAA
virtual bool disableLLVMAA() const
Definition: LLVMTCECmdLineOptions.cc:314
FalseAliasAnalyzer
Definition: FalseAliasAnalyzer.hh:40
Operation::name
virtual TCEString name() const
Definition: Operation.cc:93
LiveRangeData::regDefReaches_
MoveNodeUseMapSet regDefReaches_
Definition: LiveRangeData.hh:90
DataDependenceGraphBuilder::REGISTERS_AND_PROGRAM_OPERATIONS
@ REGISTERS_AND_PROGRAM_OPERATIONS
Definition: DataDependenceGraphBuilder.hh:121
SchedulerCmdLineOptions
Definition: SchedulerCmdLineOptions.hh:45
DataDependenceGraphBuilder::updateRegistersUsedInOrAfter
bool updateRegistersUsedInOrAfter(BBData &bbd)
Definition: DataDependenceGraphBuilder.cc:2955
Conversion::toString
static std::string toString(const T &source)
LiveRangeData::memLastKill_
MoveNodeUseMap memLastKill_
Definition: LiveRangeData.hh:100
MoveNodeUse::loop
bool loop() const
Definition: MoveNodeUse.hh:43
DataDependenceGraphBuilder::memoryCategory
TCEString memoryCategory(const MoveNodeUse &mnd)
Definition: DataDependenceGraphBuilder.cc:1999
REG_IPARAM
static const int REG_IPARAM
Definition: DataDependenceGraphBuilder.cc:102
DataDependenceGraphBuilder::cfg_
ControlFlowGraph * cfg_
Definition: DataDependenceGraphBuilder.hh:320
ProgramOperationPtr
std::shared_ptr< ProgramOperation > ProgramOperationPtr
Definition: MoveNode.hh:52
DataDependenceGraphBuilder::iterateBBs
void iterateBBs(ConstructionPhase phase)
Definition: DataDependenceGraphBuilder.cc:2345
Exception::fileName
std::string fileName() const
LiveRangeData::memDefAfter_
MoveNodeUseMapSet memDefAfter_
Definition: LiveRangeData.hh:112
MoveNode::setSourceOperationPtr
void setSourceOperationPtr(ProgramOperationPtr po)
Definition: MoveNode.cc:541
BasicBlockNode::basicBlock
TTAProgram::BasicBlock & basicBlock()
Definition: BasicBlockNode.cc:126
LiveRangeData::registersUsedInOrAfter_
std::set< TCEString > registersUsedInOrAfter_
Definition: LiveRangeData.hh:122
REG_FP
static const int REG_FP
Definition: DataDependenceGraphBuilder.cc:105
assert
#define assert(condition)
Definition: Application.hh:86
DataDependenceGraphBuilder::BBData::destPending_
ProgramOperationPtr destPending_
ProgramOperations lacking operands.
Definition: DataDependenceGraphBuilder.hh:132
DataDependenceGraphBuilder::BBData::readPending_
ProgramOperationPtr readPending_
ProgramOperations lacking result read.
Definition: DataDependenceGraphBuilder.hh:134
DataDependenceGraphBuilder::processDestination
void processDestination(class MoveNode &moveNode, ConstructionPhase phase)
Definition: DataDependenceGraphBuilder.cc:844
REG_RV_HIGH
static const int REG_RV_HIGH
Definition: DataDependenceGraphBuilder.cc:99
TTAProgram::TerminalFUPort::hintOperation
virtual Operation & hintOperation() const
Definition: TerminalFUPort.cc:262
MemoryAliasAnalyzer::AliasingResult
AliasingResult
Definition: MemoryAliasAnalyzer.hh:50
DataDependenceEdge::DEP_UNKNOWN
@ DEP_UNKNOWN
Definition: DataDependenceEdge.hh:46
SequenceTools::deleteAllItems
static void deleteAllItems(SequenceType &aSequence)
DataDependenceGraphBuilder::BasicBlockNodeSet
ControlFlowGraph::NodeSet BasicBlockNodeSet
Definition: DataDependenceGraphBuilder.hh:102
TTAProgram::ProgramAnnotation::ANN_CONSTANT_MEM
@ ANN_CONSTANT_MEM
Constant memory access.
Definition: ProgramAnnotation.hh:183
TTAProgram::ProgramAnnotation::id
ProgramAnnotation::Id id() const
Definition: ProgramAnnotation.cc:111
MoveNodeUse::ra
bool ra() const
Definition: MoveNodeUse.hh:41
MemoryAliasAnalyzer::ALIAS_TRUE
@ ALIAS_TRUE
Definition: MemoryAliasAnalyzer.hh:53
TTAProgram::Terminal::operationIndex
virtual int operationIndex() const
Definition: Terminal.cc:364
GlobalVsStackAA
Definition: GlobalVsStackAA.hh:39
DataDependenceGraphBuilder::BB_READY
@ BB_READY
BB which is queued to be processed.
Definition: DataDependenceGraphBuilder.hh:117
LiveRangeData::fuDepReaches_
MoveNodeUseSet fuDepReaches_
Definition: LiveRangeData.hh:116
abortWithError
#define abortWithError(message)
Definition: Application.hh:72
TTAMachine::SpecialRegisterPort
Definition: SpecialRegisterPort.hh:48
LiveRangeData::memUseAfter_
MoveNodeUseMapSet memUseAfter_
Definition: LiveRangeData.hh:113
REG_VRV
static const int REG_VRV
Definition: DataDependenceGraphBuilder.cc:104
TTAProgram::BasicBlock::liveRangeData_
LiveRangeData * liveRangeData_
Definition: BasicBlock.hh:111
TTAProgram::CodeSnippet::instructionCount
virtual int instructionCount() const
Definition: CodeSnippet.cc:205
DataDependenceGraph::hasSingleBBLoopRegisterAntidependencies
bool hasSingleBBLoopRegisterAntidependencies()
Definition: DataDependenceGraph.hh:383
DataDependenceEdge::DEP_RAW
@ DEP_RAW
Definition: DataDependenceEdge.hh:47
DataDependenceGraphBuilder::BB_QUEUED
@ BB_QUEUED
Basic block we have not yet encountered.
Definition: DataDependenceGraphBuilder.hh:116
ContainerTools::removeValueIfExists
static bool removeValueIfExists(ContainerType &aContainer, const ElementType &aKey)
DataDependenceGraphBuilder::createTriggerDependencies
void createTriggerDependencies(class MoveNode &moveNode, class Operation &dop)
Definition: DataDependenceGraphBuilder.cc:1596
DataDependenceGraphBuilder::updateBB
void updateBB(BBData &bbd, ConstructionPhase phase)
Definition: DataDependenceGraphBuilder.cc:2743
TTAMachine::RegisterGuard
Definition: Guard.hh:137
LLVMTCECmdLineOptions::disableAddressSpaceAA
bool disableAddressSpaceAA() const
Definition: LLVMTCECmdLineOptions.cc:319
DataDependenceGraph::updateRegUse
void updateRegUse(const MoveNodeUse &mnd, const TCEString &reg, TTAProgram::BasicBlock &bb)
Definition: DataDependenceGraph.cc:5367
DataDependenceGraphBuilder::addAliasAnalyzer
void addAliasAnalyzer(MemoryAliasAnalyzer *analyzer)
Definition: DataDependenceGraphBuilder.cc:293
TTAProgram::AnnotatedInstructionElement::hasAnnotation
bool hasAnnotation(ProgramAnnotation::Id id, const TCEString &data) const
Definition: AnnotatedInstructionElement.cc:174
OperationPool::sharesState
bool sharesState(const Operation &op)
Definition: OperationPool.cc:123
DataDependenceGraphBuilder::checkAndCreateMemDep
bool checkAndCreateMemDep(MoveNodeUse prev, MoveNodeUse mnd, DataDependenceEdge::DependenceType depType)
Definition: DataDependenceGraphBuilder.cc:1841
DataDependenceGraphBuilder::processTriggerPO
void processTriggerPO(class MoveNode &moveNode, Operation &dop)
Definition: DataDependenceGraphBuilder.cc:948
LiveRangeData
Definition: LiveRangeData.hh:47
DataDependenceGraphBuilder::rvIsParamReg_
bool rvIsParamReg_
Definition: DataDependenceGraphBuilder.hh:321
DataDependenceEdge::EDGE_FUSTATE
@ EDGE_FUSTATE
Definition: DataDependenceEdge.hh:55
TTAProgram::Move::guard
MoveGuard & guard() const
Definition: Move.cc:345
DataDependenceGraphBuilder::searchRegisterDeaths
void searchRegisterDeaths()
Definition: DataDependenceGraphBuilder.cc:2882
DataDependenceEdge::EDGE_OPERATION
@ EDGE_OPERATION
Definition: DataDependenceEdge.hh:56
Application::cmdLineOptions
static CmdLineOptions * cmdLineOptions()
Definition: Application.cc:397
DataDependenceGraph::nodeOfMove
MoveNode & nodeOfMove(const TTAProgram::Move &move)
Definition: DataDependenceGraph.cc:3600
IllegalProgram
Definition: Exception.hh:895
LiveRangeData::regFirstDefines_
MoveNodeUseMapSet regFirstDefines_
Definition: LiveRangeData.hh:87
DataDependenceGraphBuilder::currentData_
BBData * currentData_
Definition: DataDependenceGraphBuilder.hh:313
DataDependenceGraphBuilder::changeState
void changeState(BBData &bbd, BBState newState, bool priorize=false)
Definition: DataDependenceGraphBuilder.cc:2217
PRegionAliasAnalyzer
Definition: PRegionAliasAnalyzer.hh:41
__func__
#define __func__
Definition: Application.hh:67
LiveRangeData::inlineAsmRegUses_
std::set< TCEString > inlineAsmRegUses_
Definition: LiveRangeData.hh:126
DataDependenceGraphBuilder::checkAndCreateMemAntideps
void checkAndCreateMemAntideps(MoveNodeUse &mnd, std::set< MoveNodeUse > &prevNodes, DataDependenceEdge::DependenceType depType, bool traceable)
Definition: DataDependenceGraphBuilder.cc:1718
DataDependenceGraphBuilder::updateRegistersAliveAfter
bool updateRegistersAliveAfter(BBData &bbd)
Definition: DataDependenceGraphBuilder.cc:2519
BasicBlockNode
Definition: BasicBlockNode.hh:64
LiveRangeData::regLastUses_
MoveNodeUseMapSet regLastUses_
Definition: LiveRangeData.hh:79
MemoryAliasAnalyzer
Definition: MemoryAliasAnalyzer.hh:47
BasicBlockNode::isNormalBB
bool isNormalBB() const
Definition: BasicBlockNode.cc:239
DataDependenceGraphBuilder::createRegisterAntideps
void createRegisterAntideps(const TCEString &reg, MoveNodeUse &mnd, MoveNodeUseSet &predecessorNodes, DataDependenceEdge::DependenceType depType, bool guardedKillFound)
Definition: DataDependenceGraphBuilder.cc:1303
DataDependenceGraphBuilder::createRegisterDeps
void createRegisterDeps()
Definition: DataDependenceGraphBuilder.cc:2268
TTAProgram::Terminal::isGPR
virtual bool isGPR() const
Definition: Terminal.cc:107
Exception::errorMessageStack
std::string errorMessageStack(bool messagesOnly=false) const
Definition: Exception.cc:138
DataDependenceGraph::connectOrDeleteEdge
bool connectOrDeleteEdge(const MoveNode &tailNode, const MoveNode &headNode, DataDependenceEdge *edge)
Definition: DataDependenceGraph.cc:3355
BoostGraph::sinkNodes
virtual NodeSet sinkNodes() const
DataDependenceGraphBuilder::isAlwaysDifferentFU
bool isAlwaysDifferentFU(const MoveNode *srcMN, const MoveNode *dstMN)
Definition: DataDependenceGraphBuilder.cc:2994
TTAProgram::ProgramAnnotation::ANN_STACKUSE_FP_SAVE
@ ANN_STACKUSE_FP_SAVE
frame ptr save/load
Definition: ProgramAnnotation.hh:91
DataDependenceGraphBuilder::isAddressTraceable
bool isAddressTraceable(const ProgramOperation &pop)
Definition: DataDependenceGraphBuilder.cc:1974
DataDependenceGraphBuilder::iterateRegisterDeaths
void iterateRegisterDeaths()
Definition: DataDependenceGraphBuilder.cc:2924
TTAProgram::Move
Definition: Move.hh:55
DataDependenceGraphBuilder::createOperationEdges
void createOperationEdges(ProgramOperationPtr po)
Definition: DataDependenceGraphBuilder.cc:1141
DataDependenceGraphBuilder::updatePreceedingRegistersUsedAfter
void updatePreceedingRegistersUsedAfter(BBData &bbd, bool firstTime)
Definition: DataDependenceGraphBuilder.cc:2390
Exception
Definition: Exception.hh:54
MoveNodeUse::guard
bool guard() const
Definition: MoveNodeUse.hh:40
InterPassData::hasDatum
bool hasDatum(const std::string &key) const
Definition: InterPassData.cc:75
TTAProgram::ProgramAnnotation::ANN_ALLOWED_UNIT_DST
@ ANN_ALLOWED_UNIT_DST
Dst. unit candidate.
Definition: ProgramAnnotation.hh:113
LLVMTCECmdLineOptions
Definition: LLVMTCECmdLineOptions.hh:48
StackAliasAnalyzer
Definition: StackAliasAnalyzer.hh:46
TTAProgram::TerminalFUPort::isOpcodeSetting
virtual bool isOpcodeSetting() const
Definition: TerminalFUPort.cc:180
ProgramOperation::inputMoveCount
int inputMoveCount() const
Definition: ProgramOperation.cc:600
LiveRangeData::regUseAfter_
MoveNodeUseMapSet regUseAfter_
Definition: LiveRangeData.hh:95
REG_RV
static const int REG_RV
Definition: DataDependenceGraphBuilder.cc:101
LiveRangeData::regDefAfter_
MoveNodeUseMapSet regDefAfter_
Definition: LiveRangeData.hh:94
DataDependenceEdge::DEP_WAW
@ DEP_WAW
Definition: DataDependenceEdge.hh:49
Operation
Definition: Operation.hh:59
TTAProgram::AnnotatedInstructionElement::hasAnnotations
bool hasAnnotations(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:165
DataDependenceGraphBuilder::processRegWrite
void processRegWrite(MoveNodeUse mn, const TCEString &reg)
Definition: DataDependenceGraphBuilder.cc:1369
Conversion::toHexString
static std::string toHexString(T source, std::size_t digits=0, bool include0x=true)
GraphBase::writeToDotFile
virtual void writeToDotFile(const TCEString &fileName) const
TTAProgram::ProgramAnnotation::ANN_STACKUSE_RA_SAVE
@ ANN_STACKUSE_RA_SAVE
ra, new frontend
Definition: ProgramAnnotation.hh:90
TTAProgram::TerminalFUPort
Definition: TerminalFUPort.hh:56
DataDependenceGraphBuilder::bbData_
BBDataMap bbData_
Definition: DataDependenceGraphBuilder.hh:311
LiveRangeData::potentialRegKills_
std::map< TCEString, std::pair< MoveNodeUse, bool > > potentialRegKills_
Definition: LiveRangeData.hh:82
TTAProgram::TerminalFUPort::hasProgramOperation
bool hasProgramOperation() const
these methods are used to group terminals belonging to a single program operation invocation
Definition: TerminalFUPort.hh:91
options
static MachInfoCmdLineOptions options
Definition: MachInfo.cc:46
DataDependenceGraphBuilder::RA_NAME
static const TCEString RA_NAME
Definition: DataDependenceGraphBuilder.hh:318
DataDependenceGraphBuilder::processSource
void processSource(MoveNode &moveNode)
Definition: DataDependenceGraphBuilder.cc:785
Operation::usesMemory
virtual bool usesMemory() const
Definition: Operation.cc:232
MoveNode::destinationOperation
ProgramOperation & destinationOperation(unsigned int index=0) const
TTAProgram::TerminalFUPort::programOperation
ProgramOperationPtr programOperation() const
Definition: TerminalFUPort.hh:97
DataDependenceGraph::addNode
void addNode(MoveNode &moveNode)
Definition: DataDependenceGraph.cc:144
SetTools::intersection
static void intersection(const std::set< ValueType > &firstContainer, const std::set< ValueType > &secondContainer, std::set< ValueType > &intersection)
TTAProgram::AnnotatedInstructionElement::annotation
ProgramAnnotation annotation(int index, ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:100
TTAProgram::BasicBlock
Definition: BasicBlock.hh:85
MoveNode::move
TTAProgram::Move & move()
TTAMachine::BaseRegisterFile::port
virtual RFPort * port(const std::string &name) const
Definition: BaseRegisterFile.cc:129
MoveNodeUse::bbRelation
BBRelation bbRelation() const
Definition: MoveNodeUse.hh:45
ProgramOperation::toString
std::string toString() const
Definition: ProgramOperation.cc:746
DataDependenceGraphBuilder::updateMemAndFuAliveAfter
bool updateMemAndFuAliveAfter(BBData &bbd)
Definition: DataDependenceGraphBuilder.cc:2592
LiveRangeData::registersUsedAfter_
std::set< TCEString > registersUsedAfter_
Definition: LiveRangeData.hh:121
POMDisassembler::disassemble
static std::string disassemble(const TTAProgram::Move &move)
Definition: POMDisassembler.cc:629
DataDependenceGraphBuilder::currentDDG_
DataDependenceGraph * currentDDG_
Definition: DataDependenceGraphBuilder.hh:314
IllegalMachine
Definition: Exception.hh:878
TTAProgram::ProgramAnnotation::ANN_STACKUSE_SPILL
@ ANN_STACKUSE_SPILL
spilled variable
Definition: ProgramAnnotation.hh:89
DataDependenceGraphBuilder::updateMemWrite
void updateMemWrite(MoveNodeUse mnd, const TCEString &category)
Definition: DataDependenceGraphBuilder.cc:2833
DataDependenceEdge::EDGE_MEMORY
@ EDGE_MEMORY
Definition: DataDependenceEdge.hh:54
DataDependenceGraphBuilder::setSucceedingPredepsForBB
void setSucceedingPredepsForBB(TTAProgram::BasicBlock &processedBB, BasicBlockNode &successor, bool queueAll, bool loop, ConstructionPhase phase)
Definition: DataDependenceGraphBuilder.cc:2460
DataDependenceGraphBuilder::allParamRegs_
std::set< TCEString > allParamRegs_
Definition: DataDependenceGraphBuilder.hh:100
AssocTools::append
static void append(const ContainerType &src, ContainerType &dest)
DataDependenceGraph::exclusingGuards
bool exclusingGuards(const MoveNode &mn1, const MoveNode &mn2) const
Definition: DataDependenceGraph.cc:4480
DataDependenceGraphBuilder::BBState
BBState
Definition: DataDependenceGraphBuilder.hh:114
TCEString
Definition: TCEString.hh:53
DataDependenceGraphBuilder::processOperand
void processOperand(class MoveNode &moveNode, Operation &dop)
Definition: DataDependenceGraphBuilder.cc:1062
DataDependenceGraph
Definition: DataDependenceGraph.hh:67
ControlFlowGraph::entryNode
BasicBlockNode & entryNode() const
Definition: ControlFlowGraph.cc:1003
DataDependenceGraphBuilder::setSucceedingPredeps
void setSucceedingPredeps(BBData &bbd, bool queueAll, ConstructionPhase phase)
Definition: DataDependenceGraphBuilder.cc:2424
REG_SP
static const int REG_SP
Definition: DataDependenceGraphBuilder.cc:100
DataDependenceGraphBuilder::processReturn
void processReturn(MoveNode &moveNode)
Definition: DataDependenceGraphBuilder.cc:1486
DataDependenceGraphBuilder::interPassData_
InterPassData * interPassData_
Definition: DataDependenceGraphBuilder.hh:319
TTAProgram::Terminal
Definition: Terminal.hh:60
DataDependenceEdge
Definition: DataDependenceEdge.hh:43
TTAProgram::CodeSnippet::instructionAtIndex
virtual Instruction & instructionAtIndex(int index) const
Definition: CodeSnippet.cc:285
TTAProgram::Move::source
Terminal & source() const
Definition: Move.cc:302
TTAProgram::Terminal::port
virtual const TTAMachine::Port & port() const
Definition: Terminal.cc:378
DisassemblyRegister::registerName
static TCEString registerName(const TTAMachine::RegisterFile &rf, int index, char delim='.')
Definition: DisassemblyRegister.cc:95
DataDependenceGraphBuilder::hasEarlierMemWriteToSameAddressWithSameGuard
bool hasEarlierMemWriteToSameAddressWithSameGuard(MoveNodeUse &mnd, std::set< MoveNodeUse > &defines)
Definition: DataDependenceGraphBuilder.cc:1688
DataDependenceGraphBuilder::processRegUse
void processRegUse(MoveNodeUse mn, const TCEString &reg)
Definition: DataDependenceGraphBuilder.cc:1229
LLVMAliasAnalyzer::setLLVMAA
virtual void setLLVMAA(llvm::AliasAnalysis *AA)
Definition: LLVMAliasAnalyzer.cc:157
TTAMachine::RegisterFile
Definition: RegisterFile.hh:47
Conversion::toInt
static int toInt(const T &source)
TTAProgram::MoveGuard::guard
const TTAMachine::Guard & guard() const
Definition: MoveGuard.cc:86
DataDependenceGraphBuilder::hasEarlierWriteWithSameGuard
bool hasEarlierWriteWithSameGuard(MoveNodeUse &mnd, std::set< MoveNodeUse > &defines)
Definition: DataDependenceGraphBuilder.cc:1183
DataDependenceGraphBuilder::MEMORY_AND_SIDE_EFFECTS
@ MEMORY_AND_SIDE_EFFECTS
Definition: DataDependenceGraphBuilder.hh:122
TTAProgram::ProgramAnnotation
Definition: ProgramAnnotation.hh:49
OperationPool
Definition: OperationPool.hh:52
TTAProgram::Instruction::movePtr
std::shared_ptr< Move > movePtr(int i) const
Definition: Instruction.cc:216
InterPassData::datum
InterPassDatum & datum(const std::string &key)
Definition: InterPassData.cc:62
DataDependenceGraphBuilder::constructIndividualBB
void constructIndividualBB(ConstructionPhase phase)
Definition: DataDependenceGraphBuilder.cc:560
LiveRangeData::memKills_
MoveNodeUseMap memKills_
Definition: LiveRangeData.hh:103
DataDependenceEdge::DEP_WAR
@ DEP_WAR
Definition: DataDependenceEdge.hh:48
OffsetAliasAnalyzer
Definition: OffsetAliasAnalyzer.hh:46
LiveRangeData::fuDepAfter_
MoveNodeUseSet fuDepAfter_
Definition: LiveRangeData.hh:118
LiveRangeData::memDefines_
MoveNodeUseMapSet memDefines_
Definition: LiveRangeData.hh:98
BoostGraph::name
virtual const TCEString & name() const
LiveRangeData::appendUseMapSets
static bool appendUseMapSets(const MoveNodeUseMapSet &srcMap, MoveNodeUseMapSet &dstMap, bool addLoopProperty)
Definition: LiveRangeData.cc:79
BoostGraph::nodeCount
int nodeCount() const
MachineInfo::triggerIndex
static int triggerIndex(const TTAMachine::Machine &machine, const Operation &op)
Definition: MachineInfo.cc:530
DataDependenceGraph::updateRegWrite
DataDependenceGraph::EdgeSet updateRegWrite(const MoveNodeUse &mnd, const TCEString &reg, TTAProgram::BasicBlock &bb)
Definition: DataDependenceGraph.cc:5401
TTAMachine::RegisterGuard::registerFile
const RegisterFile * registerFile() const
DataDependenceEdge::EDGE_RA
@ EDGE_RA
Definition: DataDependenceEdge.hh:57
BoostGraph::successors
virtual NodeSet successors(const Node &node, bool ignoreBackEdges=false, bool ignoreForwardEdges=false) const
Operation::numberOfOutputs
virtual int numberOfOutputs() const
Definition: Operation.cc:202
DataDependenceGraphBuilder::analyzeMemoryAlias
MemoryAliasAnalyzer::AliasingResult analyzeMemoryAlias(const ProgramOperation &pop1, const ProgramOperation &pop2, MoveNodeUse::BBRelation bbInfo)
Definition: DataDependenceGraphBuilder.cc:1951
AssocTools::deleteAllValues
static void deleteAllValues(ContainerType &aMap)
LiveRangeData::memDefReaches_
MoveNodeUseMapSet memDefReaches_
Definition: LiveRangeData.hh:108
Operation::affectsCount
virtual int affectsCount() const
Definition: Operation.cc:402
DataDependenceGraphBuilder::processTriggerMemoryAndFUStates
void processTriggerMemoryAndFUStates(MoveNode &moveNode, Operation &dop)
Definition: DataDependenceGraphBuilder.cc:1040
DataDependenceGraph::hasAllRegisterAntidependencies
bool hasAllRegisterAntidependencies()
Definition: DataDependenceGraph.hh:379
BasicBlockNode::originalStartAddress
InstructionAddress originalStartAddress() const
Definition: BasicBlockNode.cc:162
TTAProgram::Instruction::moveCount
int moveCount() const
Definition: Instruction.cc:176
DataDependenceGraph::hasRegWaw
bool hasRegWaw(const MoveNodeUse &mnu, std::set< MoveNodeUse > targets) const
Definition: DataDependenceGraph.cc:5518
TTAProgram::TerminalRegister
Definition: TerminalRegister.hh:53
LiveRangeData::regFirstUses_
MoveNodeUseMapSet regFirstUses_
Definition: LiveRangeData.hh:86
DataDependenceGraphBuilder::specialRegisters_
SpecialRegisters specialRegisters_
contains stack pointer, RV and parameter registers.
Definition: DataDependenceGraphBuilder.hh:317
ProgramOperation::inputMove
MoveNode & inputMove(int index) const
Definition: ProgramOperation.cc:621
TTAProgram::AnnotatedInstructionElement::annotationCount
int annotationCount(ProgramAnnotation::Id id=ProgramAnnotation::ANN_UNDEF_ID) const
Definition: AnnotatedInstructionElement.cc:133
LiveRangeData::memUseReaches_
MoveNodeUseMapSet memUseReaches_
Definition: LiveRangeData.hh:109
DataDependenceGraph::hasIntraBBRegisterAntidependencies
bool hasIntraBBRegisterAntidependencies()
Definition: DataDependenceGraph.hh:387