lib/HLSL/ComputeViewIdState.cpp
// Only process control-dependent basic blocks for constant operands of the phi-function.
// An obvious "definition" point for a constant operand is the predecessor along corresponding edge.
// However, this may be too conservative and, as such, pick up extra control dependent BBs.
// A better "definition" point is the highest dominator where it is still legal to "insert" constant assignment.
// In this context, "legal" means that only one value "leaves" the dominator and reaches Phi.
Only process control-dependent basic blocks for constant operands of the phi-function.
An obvious "definition" point for a constant operand is the predecessor along corresponding edge.
However, this may be too conservative and, as such, pick up extra control dependent BBs.
A better "definition" point is the highest dominator where it is still legal to "insert" constant assignment.
In this context, "legal" means that only one value "leaves" the dominator and reaches Phi.
Only process control - dependent basic blocks for constant operands of the phi - function . An obvious " definition " point for a constant operand is the predecessor along corresponding edge . However this may be too conservative and as such pick up extra control dependent BBs . A better " definition " point is the highest dominator where it is still legal to " insert " constant assignment . In this context " legal " means that only one value " leaves " the dominator and reaches Phi .
void DxilViewIdState::CollectPhiCFValuesContributingToOutputRec(PHINode *pPhi,
                                                                EntryInfo &Entry,
                                                                InstructionSetType &ContributingInstructions) {
  Function *F = pPhi->getParent()->getParent();
  FuncInfo *pFuncInfo = m_FuncInfo[F].get();
  unordered_map<DomTreeNodeBase<BasicBlock> *, Value *> DomTreeMarkers;
  for (unsigned i = 0; i < pPhi->getNumOperands(); i++) {
    Value *pValue = pPhi->getIncomingValue(i);
    BasicBlock *pBB = pPhi->getIncomingBlock(i);
    DomTreeNodeBase<BasicBlock> *pDomNode = pFuncInfo->pDomTree->getNode(pBB);
    auto it = DomTreeMarkers.emplace(pDomNode, pValue);
    DXASSERT_NOMSG(it.second || it.first->second == pValue); it;
  }
  for (unsigned i = 0; i < pPhi->getNumOperands(); i++) {
    Value *pValue = pPhi->getIncomingValue(i);
    BasicBlock *pDefBB = &F->getEntryBlock();
    if (Instruction *pDefInst = dyn_cast<Instruction>(pValue)) {
      pDefBB = pDefInst->getParent();
    }
    BasicBlock *pBB = pPhi->getIncomingBlock(i);
    if (pBB == pDefBB) {
      continue; 
    }
    DomTreeNodeBase<BasicBlock> *pDomNode = pFuncInfo->pDomTree->getNode(pBB);
    pDomNode = pDomNode->getIDom();
    while (pDomNode) {
      auto it = DomTreeMarkers.emplace(pDomNode, pValue);
      if (!it.second) {
        if (it.first->second != pValue && it.first->second != nullptr) {
          if (!isa<Constant>(it.first->second) || !isa<Constant>(pValue)) {
            it.first->second = nullptr;
          }
        }
        break;
      }
      pBB = pDomNode->getBlock();
      if (pBB == pDefBB)
        break;
      pDomNode = pDomNode->getIDom();
    }
  }
  for (unsigned i = 0; i < pPhi->getNumOperands(); i++) {
    Value *pValue = pPhi->getIncomingValue(i);
    if (!isa<Constant>(pValue))
      continue;
    BasicBlock *pBB = pPhi->getIncomingBlock(i);
    DomTreeNodeBase<BasicBlock> *pDomNode = pFuncInfo->pDomTree->getNode(pBB);
    DomTreeNodeBase<BasicBlock> *pDefDomNode = pDomNode;
    while (pDomNode) {
      auto it = DomTreeMarkers.find(pDomNode);
      DXASSERT_NOMSG(it != DomTreeMarkers.end());
      if (it->second != pValue) {
        DXASSERT_NOMSG(it->second == nullptr || isa<Constant>(it->second));
        break;
      }
      pDefDomNode = pDomNode;
      pDomNode = pDomNode->getIDom();
    }
    pBB = pDefDomNode->getBlock();
    const BasicBlockSet &CtrlDepSet = pFuncInfo->CtrlDep.GetCDBlocks(pBB);
    for (BasicBlock *B : CtrlDepSet) {
      CollectValuesContributingToOutputRec(Entry, B->getTerminator(), ContributingInstructions);
    }
  }
}
void DxilViewIdState :: CollectPhiCFValuesContributingToOutputRec ( PHINode * pPhi , EntryInfo & Entry , InstructionSetType & ContributingInstructions ) { Function * F = pPhi -> getParent ( ) -> getParent ( ) ; FuncInfo * pFuncInfo = m_FuncInfo [ F ] . get ( ) ; unordered_map < DomTreeNodeBase < BasicBlock > * , Value * > DomTreeMarkers ; for ( unsigned i = 0 ; i < pPhi -> getNumOperands ( ) ; i ++ ) { Value * pValue = pPhi -> getIncomingValue ( i ) ; BasicBlock * pBB = pPhi -> getIncomingBlock ( i ) ; DomTreeNodeBase < BasicBlock > * pDomNode = pFuncInfo -> pDomTree -> getNode ( pBB ) ; auto it = DomTreeMarkers . emplace ( pDomNode , pValue ) ; DXASSERT_NOMSG ( it . second || it . first -> second == pValue ) ; it ; } for ( unsigned i = 0 ; i < pPhi -> getNumOperands ( ) ; i ++ ) { Value * pValue = pPhi -> getIncomingValue ( i ) ; BasicBlock * pDefBB = & F -> getEntryBlock ( ) ; if ( Instruction * pDefInst = dyn_cast < Instruction > ( pValue ) ) { pDefBB = pDefInst -> getParent ( ) ; } BasicBlock * pBB = pPhi -> getIncomingBlock ( i ) ; if ( pBB == pDefBB ) { continue ; } DomTreeNodeBase < BasicBlock > * pDomNode = pFuncInfo -> pDomTree -> getNode ( pBB ) ; pDomNode = pDomNode -> getIDom ( ) ; while ( pDomNode ) { auto it = DomTreeMarkers . emplace ( pDomNode , pValue ) ; if ( ! it . second ) { if ( it . first -> second != pValue && it . first -> second != nullptr ) { if ( ! isa < Constant > ( it . first -> second ) || ! isa < Constant > ( pValue ) ) { it . first -> second = nullptr ; } } break ; } pBB = pDomNode -> getBlock ( ) ; if ( pBB == pDefBB ) break ; pDomNode = pDomNode -> getIDom ( ) ; } } for ( unsigned i = 0 ; i < pPhi -> getNumOperands ( ) ; i ++ ) { Value * pValue = pPhi -> getIncomingValue ( i ) ; if ( ! isa < Constant > ( pValue ) ) continue ; BasicBlock * pBB = pPhi -> getIncomingBlock ( i ) ; DomTreeNodeBase < BasicBlock > * pDomNode = pFuncInfo -> pDomTree -> getNode ( pBB ) ; DomTreeNodeBase < BasicBlock > * pDefDomNode = pDomNode ; while ( pDomNode ) { auto it = DomTreeMarkers . find ( pDomNode ) ; DXASSERT_NOMSG ( it != DomTreeMarkers . end ( ) ) ; if ( it -> second != pValue ) { DXASSERT_NOMSG ( it -> second == nullptr || isa < Constant > ( it -> second ) ) ; break ; } pDefDomNode = pDomNode ; pDomNode = pDomNode -> getIDom ( ) ; } pBB = pDefDomNode -> getBlock ( ) ; const BasicBlockSet & CtrlDepSet = pFuncInfo -> CtrlDep . GetCDBlocks ( pBB ) ; for ( BasicBlock * B : CtrlDepSet ) { CollectValuesContributingToOutputRec ( Entry , B -> getTerminator ( ) , ContributingInstructions ) ; } } }
Only process control-dependent basic blocks for constant operands of the phi-function.
Only process control - dependent basic blocks for constant operands of the phi - function .
// Mark predecessors of each value, so that there is a legal "definition" point. // Mark the dominator tree with "definition" values, walking up to the parent. // we already handled the predecessor. // Unless both are different constants, mark the "definition" point as illegal. // If both are constants, leave the marker of the first one. // Do not go higher than a legal definition point. // Handle control dependence for Constant arguments of Phi. // Determine the higher legal "definition" point. // Handle control dependence of this constant argument highest legal "definition" point.