[llvm-commits] [llvm] r45070 - /llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp

Evan Cheng evan.cheng at apple.com
Wed Jan 2 11:29:19 PST 2008


Hi Owen,

Please make isKillInst, etc. static functions. Thanks!

Evan

On Dec 15, 2007, at 9:44 PM, Owen Anderson wrote:

> Author: resistor
> Date: Sat Dec 15 23:44:27 2007
> New Revision: 45070
>
> URL: http://llvm.org/viewvc/llvm-project?rev=45070&view=rev
> Log:
> Break local interferences in StrongPHIElimination.  One step closer...
>
> Modified:
>    llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp
>
> Modified: llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp?rev=45070&r1=45069&r2=45070&view=diff
>
> =
> =
> =
> =
> =
> =
> =
> =
> ======================================================================
> --- llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp (original)
> +++ llvm/trunk/lib/CodeGen/StrongPHIElimination.cpp Sat Dec 15  
> 23:44:27 2007
> @@ -258,6 +258,101 @@
>   return false;
> }
>
> +/// isKillInst - helper method that determines, from a VarInfo, if an
> +/// instruction kills a given register
> +bool isKillInst(LiveVariables::VarInfo& V, MachineInstr* MI) {
> +  return std::find(V.Kills.begin(), V.Kills.end(), MI) !=  
> V.Kills.end();
> +}
> +
> +/// interferes - checks for local interferences by scanning a  
> block.  The only
> +/// trick parameter is 'mode' which tells it the relationship of  
> the two
> +/// registers. 0 - defined in the same block, 1 - first properly  
> dominates
> +/// second, 2 - second properly dominates first
> +bool interferes(LiveVariables::VarInfo& First,  
> LiveVariables::VarInfo& Second,
> +                MachineBasicBlock* scan, unsigned mode) {
> +  MachineInstr* def = 0;
> +  MachineInstr* kill = 0;
> +
> +  bool interference = false;
> +
> +  // Wallk the block, checking for interferences
> +  for (MachineBasicBlock::iterator MBI = scan->begin(), MBE = scan- 
> >end();
> +       MBI != MBE; ++MBI) {
> +    MachineInstr* curr = MBI;
> +
> +    // Same defining block...
> +    if (mode == 0) {
> +      if (curr == First.DefInst) {
> +        // If we find our first DefInst, save it
> +        if (!def) {
> +          def = curr;
> +        // If there's already an unkilled DefInst, then
> +        // this is an interference
> +        } else if (!kill) {
> +          interference = true;
> +          break;
> +        // If there's a DefInst followed by a KillInst, then
> +        // they can't interfere
> +        } else {
> +          interference = false;
> +          break;
> +        }
> +      // Symmetric with the above
> +      } else if (curr == Second.DefInst ) {
> +        if (!def) {
> +          def = curr;
> +        } else if (!kill) {
> +          interference = true;
> +          break;
> +        } else {
> +          interference = false;
> +          break;
> +        }
> +      // Store KillInsts if they match up with the DefInst
> +      } else if (isKillInst(First, curr)) {
> +        if (def == First.DefInst) {
> +          kill = curr;
> +        } else if (isKillInst(Second, curr)) {
> +          if (def == Second.DefInst) {
> +            kill = curr;
> +          }
> +        }
> +      }
> +    // First properly dominates second...
> +    } else if (mode == 1) {
> +      if (curr == Second.DefInst) {
> +        // DefInst of second without kill of first is an interference
> +        if (!kill) {
> +          interference = true;
> +          break;
> +        // DefInst after a kill is a non-interference
> +        } else {
> +          interference = false;
> +          break;
> +        }
> +      // Save KillInsts of First
> +      } else if (isKillInst(First, curr)) {
> +        kill = curr;
> +      }
> +    // Symmetric with the above
> +    } else if (mode == 2) {
> +      if (curr == First.DefInst) {
> +        if (!kill) {
> +          interference = true;
> +          break;
> +        } else {
> +          interference = false;
> +          break;
> +        }
> +      } else if (isKillInst(Second, curr)) {
> +        kill = curr;
> +      }
> +    }
> +  }
> +
> +  return interference;
> +}
> +
> /// processBlock - Eliminate PHIs in the given block
> void StrongPHIElimination::processBlock(MachineBasicBlock* MBB) {
>   LiveVariables& LV = getAnalysis<LiveVariables>();
> @@ -305,6 +400,46 @@
>     processPHIUnion(P, PHIUnion, DF, localInterferences);
>
>     // FIXME: Check for local interferences
> +    for (std::vector<std::pair<unsigned, unsigned> >::iterator I =
> +        localInterferences.begin(), E = localInterferences.end();  
> I != E; ++I) {
> +      std::pair<unsigned, unsigned> p = *I;
> +
> +      LiveVariables::VarInfo& FirstInfo = LV.getVarInfo(p.first);
> +      LiveVariables::VarInfo& SecondInfo = LV.getVarInfo(p.second);
> +
> +      MachineDominatorTree& MDT =  
> getAnalysis<MachineDominatorTree>();
> +
> +      // Determine the block we need to scan and the relationship  
> between
> +      // the two registers
> +      MachineBasicBlock* scan = 0;
> +      unsigned mode = 0;
> +      if (FirstInfo.DefInst->getParent() == SecondInfo.DefInst- 
> >getParent()) {
> +        scan = FirstInfo.DefInst->getParent();
> +        mode = 0; // Same block
> +      } else if (MDT.dominates(FirstInfo.DefInst->getParent(),
> +                             SecondInfo.DefInst->getParent())) {
> +        scan = SecondInfo.DefInst->getParent();
> +        mode = 1; // First dominates second
> +      } else {
> +        scan = FirstInfo.DefInst->getParent();
> +        mode = 2; // Second dominates first
> +      }
> +
> +      // If there's an interference, we need to insert  copies
> +      if (interferes(FirstInfo, SecondInfo, scan, mode)) {
> +        // Insert copies for First
> +        for (int i = P->getNumOperands() - 1; i >= 2; i-=2) {
> +          if (P->getOperand(i-1).getReg() == p.first) {
> +            unsigned SrcReg = p.first;
> +            MachineBasicBlock* From = P->getOperand(i).getMBB();
> +
> +            Waiting[From].push_back(std::make_pair(SrcReg,
> +                                                   P- 
> >getOperand(0).getReg()));
> +            PHIUnion.erase(SrcReg);
> +          }
> +        }
> +      }
> +    }
>
>     ProcessedNames.insert(PHIUnion.begin(), PHIUnion.end());
>     ++P;
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits




More information about the llvm-commits mailing list