parent
							
								
									d4f440de0f
								
							
						
					
					
						commit
						8ec0a2b13a
					
				| 
						 | 
					@ -288,6 +288,9 @@ namespace {
 | 
				
			||||||
    static const unsigned notIn = (unsigned)(-1);
 | 
					    static const unsigned notIn = (unsigned)(-1);
 | 
				
			||||||
    std::map<SDOperand, unsigned> ExprMap;
 | 
					    std::map<SDOperand, unsigned> ExprMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    //CCInvMap sometimes (SetNE) we have the inverse CC code for free
 | 
				
			||||||
 | 
					    std::map<SDOperand, unsigned> CCInvMap;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public:
 | 
					  public:
 | 
				
			||||||
    ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
 | 
					    ISel(TargetMachine &TM) : SelectionDAGISel(AlphaLowering), AlphaLowering(TM) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					@ -300,6 +303,7 @@ namespace {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
      // Clear state used for selection.
 | 
					      // Clear state used for selection.
 | 
				
			||||||
      ExprMap.clear();
 | 
					      ExprMap.clear();
 | 
				
			||||||
 | 
					      CCInvMap.clear();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    unsigned SelectExpr(SDOperand N);
 | 
					    unsigned SelectExpr(SDOperand N);
 | 
				
			||||||
| 
						 | 
					@ -307,6 +311,7 @@ namespace {
 | 
				
			||||||
    void Select(SDOperand N);
 | 
					    void Select(SDOperand N);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    void SelectAddr(SDOperand N, unsigned& Reg, long& offset);
 | 
					    void SelectAddr(SDOperand N, unsigned& Reg, long& offset);
 | 
				
			||||||
 | 
					    void SelectBranchCC(SDOperand N);
 | 
				
			||||||
  };
 | 
					  };
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -354,6 +359,115 @@ void ISel::SelectAddr(SDOperand N, unsigned& Reg, long& offset)
 | 
				
			||||||
  return;
 | 
					  return;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					void ISel::SelectBranchCC(SDOperand N)
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					  assert(N.getOpcode() == ISD::BRCOND && "Not a BranchCC???");
 | 
				
			||||||
 | 
					  MachineBasicBlock *Dest = cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
 | 
				
			||||||
 | 
					  unsigned Opc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  Select(N.getOperand(0));  //chain
 | 
				
			||||||
 | 
					  SDOperand CC = N.getOperand(1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  if (CC.getOpcode() == ISD::SETCC)
 | 
				
			||||||
 | 
					    {
 | 
				
			||||||
 | 
					      SetCCSDNode* SetCC = dyn_cast<SetCCSDNode>(CC.Val);
 | 
				
			||||||
 | 
					      if (MVT::isInteger(SetCC->getOperand(0).getValueType())) {
 | 
				
			||||||
 | 
					        //Dropping the CC is only useful if we are comparing to 0
 | 
				
			||||||
 | 
					        bool isZero0 = false;
 | 
				
			||||||
 | 
					        bool isZero1 = false;
 | 
				
			||||||
 | 
					        bool isNE = false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if(SetCC->getOperand(0).getOpcode() == ISD::Constant &&
 | 
				
			||||||
 | 
					           cast<ConstantSDNode>(SetCC->getOperand(0))->getValue() == 0)
 | 
				
			||||||
 | 
					          isZero0 = true;
 | 
				
			||||||
 | 
					        if(SetCC->getOperand(1).getOpcode() == ISD::Constant &&
 | 
				
			||||||
 | 
					           cast<ConstantSDNode>(SetCC->getOperand(1))->getValue() == 0)
 | 
				
			||||||
 | 
					          isZero1 = true;
 | 
				
			||||||
 | 
					        if(SetCC->getCondition() == ISD::SETNE)
 | 
				
			||||||
 | 
					          isNE = true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (isZero0)
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            switch (SetCC->getCondition()) {
 | 
				
			||||||
 | 
					            default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
 | 
				
			||||||
 | 
					            case ISD::SETEQ:  Opc = Alpha::BEQ; break;
 | 
				
			||||||
 | 
					            case ISD::SETLT:  Opc = Alpha::BGT; break;
 | 
				
			||||||
 | 
					            case ISD::SETLE:  Opc = Alpha::BGE; break;
 | 
				
			||||||
 | 
					            case ISD::SETGT:  Opc = Alpha::BLT; break;
 | 
				
			||||||
 | 
					            case ISD::SETGE:  Opc = Alpha::BLE; break;
 | 
				
			||||||
 | 
					            case ISD::SETULT: Opc = Alpha::BNE; break;
 | 
				
			||||||
 | 
					            case ISD::SETUGT: assert(0 && "0 > (unsigned) x is never true"); break;
 | 
				
			||||||
 | 
					            case ISD::SETULE: assert(0 && "0 <= (unsigned) x is always true"); break;
 | 
				
			||||||
 | 
					            case ISD::SETUGE: Opc = Alpha::BEQ; break; //Technically you could have this CC
 | 
				
			||||||
 | 
					            case ISD::SETNE:  Opc = Alpha::BNE; break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            unsigned Tmp1 = SelectExpr(SetCC->getOperand(1));
 | 
				
			||||||
 | 
					            BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        else if (isZero1)
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            switch (SetCC->getCondition()) {
 | 
				
			||||||
 | 
					            default: CC.Val->dump(); assert(0 && "Unknown integer comparison!");
 | 
				
			||||||
 | 
					            case ISD::SETEQ:  Opc = Alpha::BEQ; break;
 | 
				
			||||||
 | 
					            case ISD::SETLT:  Opc = Alpha::BLT; break;
 | 
				
			||||||
 | 
					            case ISD::SETLE:  Opc = Alpha::BLE; break;
 | 
				
			||||||
 | 
					            case ISD::SETGT:  Opc = Alpha::BGT; break;
 | 
				
			||||||
 | 
					            case ISD::SETGE:  Opc = Alpha::BGE; break;
 | 
				
			||||||
 | 
					            case ISD::SETULT: assert(0 && "x (unsigned) < 0 is never true"); break;
 | 
				
			||||||
 | 
					            case ISD::SETUGT: Opc = Alpha::BNE; break;
 | 
				
			||||||
 | 
					            case ISD::SETULE: Opc = Alpha::BEQ; break; //Technically you could have this CC
 | 
				
			||||||
 | 
					            case ISD::SETUGE: assert(0 && "x (unsgined >= 0 is always true"); break;
 | 
				
			||||||
 | 
					            case ISD::SETNE:  Opc = Alpha::BNE; break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
 | 
				
			||||||
 | 
					            BuildMI(BB, Opc, 2).addReg(Tmp1).addMBB(Dest);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        else
 | 
				
			||||||
 | 
					          {
 | 
				
			||||||
 | 
					            unsigned Tmp1 = SelectExpr(CC);
 | 
				
			||||||
 | 
					            if (isNE)
 | 
				
			||||||
 | 
					              BuildMI(BB, Alpha::BEQ, 2).addReg(CCInvMap[CC]).addMBB(Dest);
 | 
				
			||||||
 | 
					            else
 | 
				
			||||||
 | 
					              BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
 | 
				
			||||||
 | 
					            return;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					      } else { //FP
 | 
				
			||||||
 | 
					        //Any comparison between 2 values should be codegened as an folded branch, as moving
 | 
				
			||||||
 | 
					        //CC to the integer register is very expensive
 | 
				
			||||||
 | 
					        //for a cmp b: c = a - b;
 | 
				
			||||||
 | 
					        //a = b: c = 0
 | 
				
			||||||
 | 
					        //a < b: c < 0
 | 
				
			||||||
 | 
					        //a > b: c > 0
 | 
				
			||||||
 | 
					        unsigned Tmp1 = SelectExpr(SetCC->getOperand(0));
 | 
				
			||||||
 | 
					        unsigned Tmp2 = SelectExpr(SetCC->getOperand(1));
 | 
				
			||||||
 | 
					        unsigned Tmp3 = MakeReg(MVT::f64);
 | 
				
			||||||
 | 
					        BuildMI(BB, Alpha::SUBT, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (SetCC->getCondition()) {
 | 
				
			||||||
 | 
					        default: CC.Val->dump(); assert(0 && "Unknown FP comparison!");
 | 
				
			||||||
 | 
					        case ISD::SETEQ: Opc = Alpha::FBEQ; break;
 | 
				
			||||||
 | 
					        case ISD::SETLT: Opc = Alpha::FBLT; break;
 | 
				
			||||||
 | 
					        case ISD::SETLE: Opc = Alpha::FBLE; break;
 | 
				
			||||||
 | 
					        case ISD::SETGT: Opc = Alpha::FBGT; break;
 | 
				
			||||||
 | 
					        case ISD::SETGE: Opc = Alpha::FBGE; break;
 | 
				
			||||||
 | 
					        case ISD::SETNE: Opc = Alpha::FBNE; break;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        BuildMI(BB, Opc, 2).addReg(Tmp3).addMBB(Dest);
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      abort(); //Should never be reached
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  else
 | 
				
			||||||
 | 
					    { //Giveup and do the stupid thing
 | 
				
			||||||
 | 
					      unsigned Tmp1 = SelectExpr(CC);
 | 
				
			||||||
 | 
					      BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
 | 
				
			||||||
 | 
					      return;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  abort(); //Should never be reached
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
 | 
					unsigned ISel::SelectExprFP(SDOperand N, unsigned Result)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
  unsigned Tmp1, Tmp2, Tmp3;
 | 
					  unsigned Tmp1, Tmp2, Tmp3;
 | 
				
			||||||
| 
						 | 
					@ -886,6 +1000,8 @@ unsigned ISel::SelectExpr(SDOperand N) {
 | 
				
			||||||
            Tmp2 = SelectExpr(N.getOperand(1));
 | 
					            Tmp2 = SelectExpr(N.getOperand(1));
 | 
				
			||||||
            Tmp3 = MakeReg(MVT::i64);
 | 
					            Tmp3 = MakeReg(MVT::i64);
 | 
				
			||||||
            BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
 | 
					            BuildMI(BB, Alpha::CMPEQ, 2, Tmp3).addReg(Tmp1).addReg(Tmp2);
 | 
				
			||||||
 | 
					            //Remeber we have the Inv for this CC
 | 
				
			||||||
 | 
					            CCInvMap[N] = Tmp3;
 | 
				
			||||||
            //and invert
 | 
					            //and invert
 | 
				
			||||||
            BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
 | 
					            BuildMI(BB, Alpha::CMPEQ, 2, Result).addReg(Alpha::R31).addReg(Tmp3);
 | 
				
			||||||
            return Result;
 | 
					            return Result;
 | 
				
			||||||
| 
						 | 
					@ -1180,13 +1296,7 @@ void ISel::Select(SDOperand N) {
 | 
				
			||||||
    assert(0 && "Node not handled yet!");
 | 
					    assert(0 && "Node not handled yet!");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  case ISD::BRCOND: {
 | 
					  case ISD::BRCOND: {
 | 
				
			||||||
    MachineBasicBlock *Dest =
 | 
					    SelectBranchCC(N);
 | 
				
			||||||
      cast<BasicBlockSDNode>(N.getOperand(2))->getBasicBlock();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Select(N.getOperand(0));  //chain
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    Tmp1 = SelectExpr(N.getOperand(1));
 | 
					 | 
				
			||||||
    BuildMI(BB, Alpha::BNE, 2).addReg(Tmp1).addMBB(Dest);
 | 
					 | 
				
			||||||
    return;
 | 
					    return;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue