[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