Skip to content
InstSelectSimple.cpp 79.9 KiB
Newer Older
//===-- InstSelectSimple.cpp - A simple instruction selector for x86 ------===//
// 
//                     The LLVM Compiler Infrastructure
//
// This file was developed by the LLVM research group and is distributed under
// the University of Illinois Open Source License. See LICENSE.TXT for details.
// 
//===----------------------------------------------------------------------===//
// This file defines a simple peephole instruction selector for the x86 target
//
//===----------------------------------------------------------------------===//

#include "X86.h"
#include "X86InstrBuilder.h"
#include "X86InstrInfo.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Function.h"
Chris Lattner's avatar
Chris Lattner committed
#include "llvm/Instructions.h"
#include "llvm/Intrinsics.h"
#include "llvm/Pass.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner's avatar
Chris Lattner committed
#include "llvm/CodeGen/SSARegMap.h"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
Chris Lattner's avatar
Chris Lattner committed
#include "llvm/Support/InstVisitor.h"
Chris Lattner's avatar
Chris Lattner committed
/// BMI - A special BuildMI variant that takes an iterator to insert the
Chris Lattner's avatar
Chris Lattner committed
/// instruction at as well as a basic block.  This is the version for when you
/// have a destination register in mind.
Brian Gaeke's avatar
 
Brian Gaeke committed
inline static MachineInstrBuilder BMI(MachineBasicBlock *MBB,
Chris Lattner's avatar
Chris Lattner committed
                                      MachineBasicBlock::iterator &I,
Chris Lattner's avatar
Chris Lattner committed
                                      int Opcode, unsigned NumOperands,
Chris Lattner's avatar
Chris Lattner committed
                                      unsigned DestReg) {
Chris Lattner's avatar
Chris Lattner committed
  assert(I >= MBB->begin() && I <= MBB->end() && "Bad iterator!");
Chris Lattner's avatar
Chris Lattner committed
  MachineInstr *MI = new MachineInstr(Opcode, NumOperands+1, true, true);
  I = MBB->insert(I, MI)+1;
Chris Lattner's avatar
Chris Lattner committed
  return MachineInstrBuilder(MI).addReg(DestReg, MOTy::Def);
}

Chris Lattner's avatar
Chris Lattner committed
/// BMI - A special BuildMI variant that takes an iterator to insert the
/// instruction at as well as a basic block.
Brian Gaeke's avatar
 
Brian Gaeke committed
inline static MachineInstrBuilder BMI(MachineBasicBlock *MBB,
Chris Lattner's avatar
Chris Lattner committed
                                      MachineBasicBlock::iterator &I,
Chris Lattner's avatar
Chris Lattner committed
                                      int Opcode, unsigned NumOperands) {
Chris Lattner's avatar
Chris Lattner committed
  assert(I >= MBB->begin() && I <= MBB->end() && "Bad iterator!");
Chris Lattner's avatar
Chris Lattner committed
  MachineInstr *MI = new MachineInstr(Opcode, NumOperands, true, true);
  I = MBB->insert(I, MI)+1;
Chris Lattner's avatar
Chris Lattner committed
  return MachineInstrBuilder(MI);
}

namespace {
  struct ISel : public FunctionPass, InstVisitor<ISel> {
    TargetMachine &TM;
    MachineFunction *F;                 // The function we are compiling into
    MachineBasicBlock *BB;              // The current MBB we are compiling
    int VarArgsFrameIndex;              // FrameIndex for start of varargs area

    std::map<Value*, unsigned> RegMap;  // Mapping between Val's and SSA Regs

Chris Lattner's avatar
Chris Lattner committed
    // MBBMap - Mapping between LLVM BB -> Machine BB
    std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;

    ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {}

    /// runOnFunction - Top level implementation of instruction selection for
    /// the entire function.
    ///
    bool runOnFunction(Function &Fn) {
      F = &MachineFunction::construct(&Fn, TM);
      // Create all of the machine basic blocks for the function...
Chris Lattner's avatar
Chris Lattner committed
      for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
        F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));

Chris Lattner's avatar
Chris Lattner committed
      BB = &F->front();

      // Copy incoming arguments off of the stack...
Chris Lattner's avatar
Chris Lattner committed

Chris Lattner's avatar
Chris Lattner committed
      // Instruction select everything except PHI nodes
Chris Lattner's avatar
Chris Lattner committed

      // Select the PHI nodes
      SelectPHINodes();

      RegMap.clear();
Chris Lattner's avatar
Chris Lattner committed
      MBBMap.clear();
      // We always build a machine code representation for the function
      return true;
Chris Lattner's avatar
Chris Lattner committed
    virtual const char *getPassName() const {
      return "X86 Simple Instruction Selection";
    }

    /// visitBasicBlock - This method is called when we are visiting a new basic
Chris Lattner's avatar
Chris Lattner committed
    /// block.  This simply creates a new MachineBasicBlock to emit code into
    /// and adds it to the current MachineFunction.  Subsequent visit* for
    /// instructions will be invoked for all instructions in the basic block.
    ///
    void visitBasicBlock(BasicBlock &LLVM_BB) {
Chris Lattner's avatar
Chris Lattner committed
      BB = MBBMap[&LLVM_BB];
    /// LoadArgumentsToVirtualRegs - Load all of the arguments to this function
    /// from the stack into virtual registers.
    ///
    void LoadArgumentsToVirtualRegs(Function &F);
Chris Lattner's avatar
Chris Lattner committed

    /// SelectPHINodes - Insert machine code to generate phis.  This is tricky
    /// because we have to generate our sources into the source basic blocks,
    /// not the current one.
    ///
    void SelectPHINodes();

    // Visitation methods for various instructions.  These methods simply emit
    // fixed X86 code for each instruction.
    //
    void visitReturnInst(ReturnInst &RI);
    void visitBranchInst(BranchInst &BI);
      unsigned Reg;
      const Type *Ty;
      ValueRecord(unsigned R, const Type *T) : Val(0), Reg(R), Ty(T) {}
      ValueRecord(Value *V) : Val(V), Reg(0), Ty(V->getType()) {}
    };
    void doCall(const ValueRecord &Ret, MachineInstr *CallMI,
                const std::vector<ValueRecord> &Args);
    void visitCallInst(CallInst &I);
    void visitIntrinsicCall(LLVMIntrinsic::ID ID, CallInst &I);
    void visitSimpleBinary(BinaryOperator &B, unsigned OpcodeClass);
Chris Lattner's avatar
Chris Lattner committed
    void visitAdd(BinaryOperator &B) { visitSimpleBinary(B, 0); }
    void visitSub(BinaryOperator &B) { visitSimpleBinary(B, 1); }
    void doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI,
                    unsigned DestReg, const Type *DestTy,
                    unsigned Op0Reg, unsigned Op1Reg);
    void doMultiplyConst(MachineBasicBlock *MBB, 
                         MachineBasicBlock::iterator &MBBI,
                         unsigned DestReg, const Type *DestTy,
                         unsigned Op0Reg, unsigned Op1Val);
    void visitMul(BinaryOperator &B);
    void visitDiv(BinaryOperator &B) { visitDivRem(B); }
    void visitRem(BinaryOperator &B) { visitDivRem(B); }
    void visitDivRem(BinaryOperator &B);

    // Bitwise operators
Chris Lattner's avatar
Chris Lattner committed
    void visitAnd(BinaryOperator &B) { visitSimpleBinary(B, 2); }
    void visitOr (BinaryOperator &B) { visitSimpleBinary(B, 3); }
    void visitXor(BinaryOperator &B) { visitSimpleBinary(B, 4); }
    // Comparison operators...
    void visitSetCondInst(SetCondInst &I);
    unsigned EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
                            MachineBasicBlock *MBB,
                            MachineBasicBlock::iterator &MBBI);
    
    // Memory Instructions
    void visitLoadInst(LoadInst &I);
    void visitStoreInst(StoreInst &I);
Brian Gaeke's avatar
 
Brian Gaeke committed
    void visitGetElementPtrInst(GetElementPtrInst &I);
    void visitAllocaInst(AllocaInst &I);
    void visitMallocInst(MallocInst &I);
    void visitFreeInst(FreeInst &I);
Brian Gaeke's avatar
 
Brian Gaeke committed
    
    void visitShiftInst(ShiftInst &I);
Chris Lattner's avatar
Chris Lattner committed
    void visitPHINode(PHINode &I) {}      // PHI nodes handled by second pass
    void visitCastInst(CastInst &I);
    void visitVANextInst(VANextInst &I);
    void visitVAArgInst(VAArgInst &I);

    void visitInstruction(Instruction &I) {
      std::cerr << "Cannot instruction select: " << I;
      abort();
    }

Brian Gaeke's avatar
 
Brian Gaeke committed
    /// promote32 - Make a value 32-bits wide, and put it somewhere.
    ///
    void promote32(unsigned targetReg, const ValueRecord &VR);

    /// emitGEPOperation - Common code shared between visitGetElementPtrInst and
    /// constant expression GEP support.
    ///
Chris Lattner's avatar
Chris Lattner committed
    void emitGEPOperation(MachineBasicBlock *BB, MachineBasicBlock::iterator&IP,
Chris Lattner's avatar
Chris Lattner committed
                          Value *Src, User::op_iterator IdxBegin,
                          User::op_iterator IdxEnd, unsigned TargetReg);

    /// emitCastOperation - Common code shared between visitCastInst and
    /// constant expression cast support.
    void emitCastOperation(MachineBasicBlock *BB,MachineBasicBlock::iterator&IP,
                           Value *Src, const Type *DestTy, unsigned TargetReg);

    /// emitSimpleBinaryOperation - Common code shared between visitSimpleBinary
    /// and constant expression support.
    void emitSimpleBinaryOperation(MachineBasicBlock *BB,
                                   MachineBasicBlock::iterator &IP,
                                   Value *Op0, Value *Op1,
                                   unsigned OperatorClass, unsigned TargetReg);

    void emitDivRemOperation(MachineBasicBlock *BB,
                             MachineBasicBlock::iterator &IP,
                             unsigned Op0Reg, unsigned Op1Reg, bool isDiv,
                             const Type *Ty, unsigned TargetReg);

    /// emitSetCCOperation - Common code shared between visitSetCondInst and
    /// constant expression support.
    void emitSetCCOperation(MachineBasicBlock *BB,
                            MachineBasicBlock::iterator &IP,
                            Value *Op0, Value *Op1, unsigned Opcode,
                            unsigned TargetReg);
 

    /// copyConstantToRegister - Output the instructions required to put the
    /// specified constant into the specified register.
    ///
    void copyConstantToRegister(MachineBasicBlock *MBB,
                                MachineBasicBlock::iterator &MBBI,
                                Constant *C, unsigned Reg);
    /// makeAnotherReg - This method returns the next register number we haven't
    /// yet used.
    ///
    /// Long values are handled somewhat specially.  They are always allocated
    /// as pairs of 32 bit integer values.  The register number returned is the
    /// lower 32 bits of the long value, and the regNum+1 is the upper 32 bits
    /// of the long value.
    ///
    unsigned makeAnotherReg(const Type *Ty) {
      assert(dynamic_cast<const X86RegisterInfo*>(TM.getRegisterInfo()) &&
             "Current target doesn't have X86 reg info??");
      const X86RegisterInfo *MRI =
        static_cast<const X86RegisterInfo*>(TM.getRegisterInfo());
      if (Ty == Type::LongTy || Ty == Type::ULongTy) {
        const TargetRegisterClass *RC = MRI->getRegClassForType(Type::IntTy);
        // Create the lower part
        F->getSSARegMap()->createVirtualRegister(RC);
        // Create the upper part.
        return F->getSSARegMap()->createVirtualRegister(RC)-1;
      // Add the mapping of regnumber => reg class to MachineFunction
      const TargetRegisterClass *RC = MRI->getRegClassForType(Ty);
      return F->getSSARegMap()->createVirtualRegister(RC);
Brian Gaeke's avatar
 
Brian Gaeke committed
    }

    /// getReg - This method turns an LLVM value into a register number.  This
    /// is guaranteed to produce the same register number for a particular value
    /// every time it is queried.
    ///
    unsigned getReg(Value &V) { return getReg(&V); }  // Allow references
Chris Lattner's avatar
Chris Lattner committed
    unsigned getReg(Value *V) {
      // Just append to the end of the current bb.
      MachineBasicBlock::iterator It = BB->end();
      return getReg(V, BB, It);
    }
Brian Gaeke's avatar
 
Brian Gaeke committed
    unsigned getReg(Value *V, MachineBasicBlock *MBB,
Chris Lattner's avatar
Chris Lattner committed
                    MachineBasicBlock::iterator &IPt) {
      unsigned &Reg = RegMap[V];
        Reg = makeAnotherReg(V->getType());
Chris Lattner's avatar
Chris Lattner committed
      // If this operand is a constant, emit the code to copy the constant into
      // the register here...
      //
      if (Constant *C = dyn_cast<Constant>(V)) {
        copyConstantToRegister(MBB, IPt, C, Reg);
Chris Lattner's avatar
Chris Lattner committed
        RegMap.erase(V);  // Assign a new name to this constant if ref'd again
      } else if (GlobalValue *GV = dyn_cast<GlobalValue>(V)) {
        // Move the address of the global into the register
        BMI(MBB, IPt, X86::MOVir32, 1, Reg).addGlobalAddress(GV);
Chris Lattner's avatar
Chris Lattner committed
        RegMap.erase(V);  // Assign a new name to this address if ref'd again
/// TypeClass - Used by the X86 backend to group LLVM types by their basic X86
/// Representation.
///
enum TypeClass {
Chris Lattner's avatar
Chris Lattner committed
  cByte, cShort, cInt, cFP, cLong
/// getClass - Turn a primitive type into a "class" number which is based on the
/// size of the type, and whether or not it is floating point.
///
static inline TypeClass getClass(const Type *Ty) {
  switch (Ty->getPrimitiveID()) {
  case Type::SByteTyID:
  case Type::UByteTyID:   return cByte;      // Byte operands are class #0
  case Type::UShortTyID:  return cShort;     // Short operands are class #1
  case Type::IntTyID:
  case Type::UIntTyID:
  case Type::PointerTyID: return cInt;       // Int's and pointers are class #2
Chris Lattner's avatar
Chris Lattner committed
  case Type::FloatTyID:
  case Type::DoubleTyID:  return cFP;        // Floating Point is #3
  case Type::ULongTyID:   return cLong;      // Longs are class #4
  default:
    assert(0 && "Invalid type to getClass!");
    return cByte;  // not reached
// getClassB - Just like getClass, but treat boolean values as bytes.
static inline TypeClass getClassB(const Type *Ty) {
  if (Ty == Type::BoolTy) return cByte;
  return getClass(Ty);
}

/// copyConstantToRegister - Output the instructions required to put the
/// specified constant into the specified register.
///
void ISel::copyConstantToRegister(MachineBasicBlock *MBB,
                                  MachineBasicBlock::iterator &IP,
                                  Constant *C, unsigned R) {
  if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C)) {
    unsigned Class = 0;
    switch (CE->getOpcode()) {
    case Instruction::GetElementPtr:
Brian Gaeke's avatar
Brian Gaeke committed
      emitGEPOperation(MBB, IP, CE->getOperand(0),
Chris Lattner's avatar
Chris Lattner committed
                       CE->op_begin()+1, CE->op_end(), R);
    case Instruction::Cast:
      emitCastOperation(MBB, IP, CE->getOperand(0), CE->getType(), R);
    case Instruction::Xor: ++Class; // FALL THROUGH
    case Instruction::Or:  ++Class; // FALL THROUGH
    case Instruction::And: ++Class; // FALL THROUGH
    case Instruction::Sub: ++Class; // FALL THROUGH
    case Instruction::Add:
      emitSimpleBinaryOperation(MBB, IP, CE->getOperand(0), CE->getOperand(1),
                                Class, R);
      return;

    case Instruction::Mul: {
      unsigned Op0Reg = getReg(CE->getOperand(0), MBB, IP);
      unsigned Op1Reg = getReg(CE->getOperand(1), MBB, IP);
      doMultiply(MBB, IP, R, CE->getType(), Op0Reg, Op1Reg);
      return;
    }
    case Instruction::Div:
    case Instruction::Rem: {
      unsigned Op0Reg = getReg(CE->getOperand(0), MBB, IP);
      unsigned Op1Reg = getReg(CE->getOperand(1), MBB, IP);
      emitDivRemOperation(MBB, IP, Op0Reg, Op1Reg,
                          CE->getOpcode() == Instruction::Div,
                          CE->getType(), R);
      return;
    }

    case Instruction::SetNE:
    case Instruction::SetEQ:
    case Instruction::SetLT:
    case Instruction::SetGT:
    case Instruction::SetLE:
    case Instruction::SetGE:
      emitSetCCOperation(MBB, IP, CE->getOperand(0), CE->getOperand(1),
                         CE->getOpcode(), R);
      return;

    default:
      std::cerr << "Offending expr: " << C << "\n";
      assert(0 && "Constant expression not yet handled!\n");
Brian Gaeke's avatar
 
Brian Gaeke committed
  }
    unsigned Class = getClassB(C->getType());

    if (Class == cLong) {
      // Copy the value into the register pair.
      uint64_t Val = cast<ConstantInt>(C)->getRawValue();
      BMI(MBB, IP, X86::MOVir32, 1, R).addZImm(Val & 0xFFFFFFFF);
      BMI(MBB, IP, X86::MOVir32, 1, R+1).addZImm(Val >> 32);
      return;
    }

Chris Lattner's avatar
Chris Lattner committed
    assert(Class <= cInt && "Type not handled yet!");

    static const unsigned IntegralOpcodeTab[] = {
      X86::MOVir8, X86::MOVir16, X86::MOVir32
    };

    if (C->getType() == Type::BoolTy) {
      BMI(MBB, IP, X86::MOVir8, 1, R).addZImm(C == ConstantBool::True);
      ConstantInt *CI = cast<ConstantInt>(C);
      BMI(MBB, IP, IntegralOpcodeTab[Class], 1, R).addZImm(CI->getRawValue());
Chris Lattner's avatar
Chris Lattner committed
  } else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
    double Value = CFP->getValue();
    if (Value == +0.0)
      BMI(MBB, IP, X86::FLD0, 0, R);
    else if (Value == +1.0)
      BMI(MBB, IP, X86::FLD1, 0, R);
    else {
      // Otherwise we need to spill the constant to memory...
      MachineConstantPool *CP = F->getConstantPool();
      unsigned CPI = CP->getConstantPoolIndex(CFP);
      const Type *Ty = CFP->getType();

      assert(Ty == Type::FloatTy || Ty == Type::DoubleTy && "Unknown FP type!");
      unsigned LoadOpcode = Ty == Type::FloatTy ? X86::FLDr32 : X86::FLDr64;
      addConstantPoolReference(BMI(MBB, IP, LoadOpcode, 4, R), CPI);
Chris Lattner's avatar
Chris Lattner committed
  } else if (isa<ConstantPointerNull>(C)) {
Brian Gaeke's avatar
 
Brian Gaeke committed
    // Copy zero (null pointer) to the register.
Brian Gaeke's avatar
 
Brian Gaeke committed
    BMI(MBB, IP, X86::MOVir32, 1, R).addZImm(0);
  } else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) {
Brian Gaeke's avatar
Brian Gaeke committed
    unsigned SrcReg = getReg(CPR->getValue(), MBB, IP);
Brian Gaeke's avatar
 
Brian Gaeke committed
    BMI(MBB, IP, X86::MOVrr32, 1, R).addReg(SrcReg);
Brian Gaeke's avatar
 
Brian Gaeke committed
    std::cerr << "Offending constant: " << C << "\n";
    assert(0 && "Type not handled yet!");
/// LoadArgumentsToVirtualRegs - Load all of the arguments to this function from
/// the stack into virtual registers.
///
void ISel::LoadArgumentsToVirtualRegs(Function &Fn) {
  // Emit instructions to load the arguments...  On entry to a function on the
  // X86, the stack frame looks like this:
  //
  // [ESP] -- return address
  // [ESP + 4] -- first argument (leftmost lexically)
  // [ESP + 8] -- second argument, if first argument is four bytes in size
  unsigned ArgOffset = 0;   // Frame mechanisms handle retaddr slot
  MachineFrameInfo *MFI = F->getFrameInfo();

  for (Function::aiterator I = Fn.abegin(), E = Fn.aend(); I != E; ++I) {
    unsigned Reg = getReg(*I);
    
    int FI;          // Frame object index
    switch (getClassB(I->getType())) {
    case cByte:
      FI = MFI->CreateFixedObject(1, ArgOffset);
      addFrameReference(BuildMI(BB, X86::MOVmr8, 4, Reg), FI);
      break;
    case cShort:
      FI = MFI->CreateFixedObject(2, ArgOffset);
      addFrameReference(BuildMI(BB, X86::MOVmr16, 4, Reg), FI);
      break;
    case cInt:
      FI = MFI->CreateFixedObject(4, ArgOffset);
      addFrameReference(BuildMI(BB, X86::MOVmr32, 4, Reg), FI);
      break;
    case cLong:
      FI = MFI->CreateFixedObject(8, ArgOffset);
      addFrameReference(BuildMI(BB, X86::MOVmr32, 4, Reg), FI);
      addFrameReference(BuildMI(BB, X86::MOVmr32, 4, Reg+1), FI, 4);
      ArgOffset += 4;   // longs require 4 additional bytes
      break;
    case cFP:
      unsigned Opcode;
      if (I->getType() == Type::FloatTy) {
        Opcode = X86::FLDr32;
        FI = MFI->CreateFixedObject(4, ArgOffset);
        Opcode = X86::FLDr64;
        FI = MFI->CreateFixedObject(8, ArgOffset);
        ArgOffset += 4;   // doubles require 4 additional bytes
      }
      addFrameReference(BuildMI(BB, Opcode, 4, Reg), FI);
      break;
    default:
      assert(0 && "Unhandled argument type!");
    }
    ArgOffset += 4;  // Each argument takes at least 4 bytes on the stack...

  // If the function takes variable number of arguments, add a frame offset for
  // the start of the first vararg value... this is used to expand
  // llvm.va_start.
  if (Fn.getFunctionType()->isVarArg())
    VarArgsFrameIndex = MFI->CreateFixedObject(1, ArgOffset);
Chris Lattner's avatar
Chris Lattner committed
/// SelectPHINodes - Insert machine code to generate phis.  This is tricky
/// because we have to generate our sources into the source basic blocks, not
/// the current one.
///
void ISel::SelectPHINodes() {
  const TargetInstrInfo &TII = TM.getInstrInfo();
Chris Lattner's avatar
Chris Lattner committed
  const Function &LF = *F->getFunction();  // The LLVM function...
  for (Function::const_iterator I = LF.begin(), E = LF.end(); I != E; ++I) {
    const BasicBlock *BB = I;
    MachineBasicBlock *MBB = MBBMap[I];

    // Loop over all of the PHI nodes in the LLVM basic block...
    unsigned NumPHIs = 0;
    for (BasicBlock::const_iterator I = BB->begin();
         PHINode *PN = const_cast<PHINode*>(dyn_cast<PHINode>(I)); ++I) {
Chris Lattner's avatar
Chris Lattner committed
      // Create a new machine instr PHI node, and insert it.
      unsigned PHIReg = getReg(*PN);
      MachineInstr *PhiMI = BuildMI(X86::PHI, PN->getNumOperands(), PHIReg);
      MBB->insert(MBB->begin()+NumPHIs++, PhiMI);

      MachineInstr *LongPhiMI = 0;
      if (PN->getType() == Type::LongTy || PN->getType() == Type::ULongTy) {
        LongPhiMI = BuildMI(X86::PHI, PN->getNumOperands(), PHIReg+1);
        MBB->insert(MBB->begin()+NumPHIs++, LongPhiMI);
      // PHIValues - Map of blocks to incoming virtual registers.  We use this
      // so that we only initialize one incoming value for a particular block,
      // even if the block has multiple entries in the PHI node.
      //
      std::map<MachineBasicBlock*, unsigned> PHIValues;

Chris Lattner's avatar
Chris Lattner committed
      for (unsigned i = 0, e = PN->getNumIncomingValues(); i != e; ++i) {
        MachineBasicBlock *PredMBB = MBBMap[PN->getIncomingBlock(i)];
        unsigned ValReg;
        std::map<MachineBasicBlock*, unsigned>::iterator EntryIt =
          PHIValues.lower_bound(PredMBB);

        if (EntryIt != PHIValues.end() && EntryIt->first == PredMBB) {
          // We already inserted an initialization of the register for this
          // predecessor.  Recycle it.
          ValReg = EntryIt->second;

        } else {        
          // Get the incoming value into a virtual register.
          Value *Val = PN->getIncomingValue(i);

          // If this is a constant or GlobalValue, we may have to insert code
          // into the basic block to compute it into a virtual register.
          if (isa<Constant>(Val) || isa<GlobalValue>(Val)) {
            // Because we don't want to clobber any values which might be in
            // physical registers with the computation of this constant (which
            // might be arbitrarily complex if it is a constant expression),
            // just insert the computation at the top of the basic block.
            MachineBasicBlock::iterator PI = PredMBB->begin();

            // Skip over any PHI nodes though!
            while (PI != PredMBB->end() && (*PI)->getOpcode() == X86::PHI)
              ++PI;

            ValReg = getReg(Val, PredMBB, PI);
          } else {
            ValReg = getReg(Val);
          }

          // Remember that we inserted a value for this PHI for this predecessor
          PHIValues.insert(EntryIt, std::make_pair(PredMBB, ValReg));
        }
        PhiMI->addRegOperand(ValReg);
        PhiMI->addMachineBasicBlockOperand(PredMBB);
        if (LongPhiMI) {
          LongPhiMI->addRegOperand(ValReg+1);
          LongPhiMI->addMachineBasicBlockOperand(PredMBB);
        }
// canFoldSetCCIntoBranch - Return the setcc instruction if we can fold it into
// the conditional branch instruction which is the only user of the cc
// instruction.  This is the case if the conditional branch is the only user of
// the setcc, and if the setcc is in the same basic block as the conditional
// branch.  We also don't handle long arguments below, so we reject them here as
// well.
//
static SetCondInst *canFoldSetCCIntoBranch(Value *V) {
  if (SetCondInst *SCI = dyn_cast<SetCondInst>(V))
    if (SCI->hasOneUse() && isa<BranchInst>(SCI->use_back()) &&
        SCI->getParent() == cast<BranchInst>(SCI->use_back())->getParent()) {
      const Type *Ty = SCI->getOperand(0)->getType();
      if (Ty != Type::LongTy && Ty != Type::ULongTy)
        return SCI;
    }
  return 0;
}
// Return a fixed numbering for setcc instructions which does not depend on the
// order of the opcodes.
//
static unsigned getSetCCNumber(unsigned Opcode) {
  switch(Opcode) {
  default: assert(0 && "Unknown setcc instruction!");
  case Instruction::SetEQ: return 0;
  case Instruction::SetNE: return 1;
  case Instruction::SetLT: return 2;
  case Instruction::SetGE: return 3;
  case Instruction::SetGT: return 4;
  case Instruction::SetLE: return 5;
  }
}

// LLVM  -> X86 signed  X86 unsigned
// -----    ----------  ------------
// seteq -> sete        sete
// setne -> setne       setne
// setlt -> setl        setb
// setge -> setge       setae
// setgt -> setg        seta
// setle -> setle       setbe
// ----
//          sets                       // Used by comparison with 0 optimization
//          setns
static const unsigned SetCCOpcodeTab[2][8] = {
  { X86::SETEr, X86::SETNEr, X86::SETBr, X86::SETAEr, X86::SETAr, X86::SETBEr,
    0, 0 },
  { X86::SETEr, X86::SETNEr, X86::SETLr, X86::SETGEr, X86::SETGr, X86::SETLEr,
    X86::SETSr, X86::SETNSr },
// EmitComparison - This function emits a comparison of the two operands,
// returning the extended setcc code to use.
unsigned ISel::EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
                              MachineBasicBlock *MBB,
                              MachineBasicBlock::iterator &IP) {
  // The arguments are already supposed to be of the same type.
  const Type *CompTy = Op0->getType();
  unsigned Class = getClassB(CompTy);
  unsigned Op0r = getReg(Op0, MBB, IP);

  // Special case handling of: cmp R, i
  if (Class == cByte || Class == cShort || Class == cInt)
    if (ConstantInt *CI = dyn_cast<ConstantInt>(Op1)) {
      uint64_t Op1v = cast<ConstantInt>(CI)->getRawValue();

      // Mask off any upper bits of the constant, if there are any...
      Op1v &= (1ULL << (8 << Class)) - 1;

      // If this is a comparison against zero, emit more efficient code.  We
      // can't handle unsigned comparisons against zero unless they are == or
      // !=.  These should have been strength reduced already anyway.
      if (Op1v == 0 && (CompTy->isSigned() || OpNum < 2)) {
        static const unsigned TESTTab[] = {
          X86::TESTrr8, X86::TESTrr16, X86::TESTrr32
        };
        BMI(MBB, IP, TESTTab[Class], 2).addReg(Op0r).addReg(Op0r);

        if (OpNum == 2) return 6;   // Map jl -> js
        if (OpNum == 3) return 7;   // Map jg -> jns
        return OpNum;

      static const unsigned CMPTab[] = {
        X86::CMPri8, X86::CMPri16, X86::CMPri32
      };

      BMI(MBB, IP, CMPTab[Class], 2).addReg(Op0r).addZImm(Op1v);
      return OpNum;
  unsigned Op1r = getReg(Op1, MBB, IP);
Chris Lattner's avatar
Chris Lattner committed
  switch (Class) {
  default: assert(0 && "Unknown type class!");
Chris Lattner's avatar
Chris Lattner committed
    // Emit: cmp <var1>, <var2> (do the comparison).  We can
    // compare 8-bit with 8-bit, 16-bit with 16-bit, 32-bit with
    // 32-bit.
  case cByte:
    BMI(MBB, IP, X86::CMPrr8, 2).addReg(Op0r).addReg(Op1r);
Chris Lattner's avatar
Chris Lattner committed
    break;
  case cShort:
    BMI(MBB, IP, X86::CMPrr16, 2).addReg(Op0r).addReg(Op1r);
Chris Lattner's avatar
Chris Lattner committed
    break;
  case cInt:
    BMI(MBB, IP, X86::CMPrr32, 2).addReg(Op0r).addReg(Op1r);
Chris Lattner's avatar
Chris Lattner committed
    break;
    BMI(MBB, IP, X86::FpUCOM, 2).addReg(Op0r).addReg(Op1r);
    BMI(MBB, IP, X86::FNSTSWr8, 0);
    BMI(MBB, IP, X86::SAHF, 1);
Chris Lattner's avatar
Chris Lattner committed
    break;
Chris Lattner's avatar
Chris Lattner committed
  case cLong:
    if (OpNum < 2) {    // seteq, setne
      unsigned LoTmp = makeAnotherReg(Type::IntTy);
      unsigned HiTmp = makeAnotherReg(Type::IntTy);
      unsigned FinalTmp = makeAnotherReg(Type::IntTy);
      BMI(MBB, IP, X86::XORrr32, 2, LoTmp).addReg(Op0r).addReg(Op1r);
      BMI(MBB, IP, X86::XORrr32, 2, HiTmp).addReg(Op0r+1).addReg(Op1r+1);
      BMI(MBB, IP, X86::ORrr32,  2, FinalTmp).addReg(LoTmp).addReg(HiTmp);
      break;  // Allow the sete or setne to be generated from flags set by OR
    } else {
      // Emit a sequence of code which compares the high and low parts once
      // each, then uses a conditional move to handle the overflow case.  For
      // example, a setlt for long would generate code like this:
      //
      // AL = lo(op1) < lo(op2)   // Signedness depends on operands
      // BL = hi(op1) < hi(op2)   // Always unsigned comparison
      // dest = hi(op1) == hi(op2) ? AL : BL;
      //
      // FIXME: This would be much better if we had hierarchical register
      // classes!  Until then, hardcode registers so that we can deal with their
      // aliases (because we don't have conditional byte moves).
      //
      BMI(MBB, IP, X86::CMPrr32, 2).addReg(Op0r).addReg(Op1r);
      BMI(MBB, IP, SetCCOpcodeTab[0][OpNum], 0, X86::AL);
      BMI(MBB, IP, X86::CMPrr32, 2).addReg(Op0r+1).addReg(Op1r+1);
      BMI(MBB, IP, SetCCOpcodeTab[CompTy->isSigned()][OpNum], 0, X86::BL);
      BMI(MBB, IP, X86::IMPLICIT_DEF, 0, X86::BH);
      BMI(MBB, IP, X86::IMPLICIT_DEF, 0, X86::AH);
      BMI(MBB, IP, X86::CMOVErr16, 2, X86::BX).addReg(X86::BX).addReg(X86::AX);
      // NOTE: visitSetCondInst knows that the value is dumped into the BL
      // register at this point for long values...
}


/// SetCC instructions - Here we just emit boilerplate code to set a byte-sized
/// register, then move it to wherever the result should be. 
///
void ISel::visitSetCondInst(SetCondInst &I) {
  if (canFoldSetCCIntoBranch(&I)) return;  // Fold this into a branch...

  unsigned DestReg = getReg(I);
  MachineBasicBlock::iterator MII = BB->end();
  emitSetCCOperation(BB, MII, I.getOperand(0), I.getOperand(1), I.getOpcode(),
                     DestReg);
}
/// emitSetCCOperation - Common code shared between visitSetCondInst and
/// constant expression support.
void ISel::emitSetCCOperation(MachineBasicBlock *MBB,
                              MachineBasicBlock::iterator &IP,
                              Value *Op0, Value *Op1, unsigned Opcode,
                              unsigned TargetReg) {
  unsigned OpNum = getSetCCNumber(Opcode);
  OpNum = EmitComparison(OpNum, Op0, Op1, MBB, IP);
  const Type *CompTy = Op0->getType();
  unsigned CompClass = getClassB(CompTy);
  bool isSigned = CompTy->isSigned() && CompClass != cFP;

  if (CompClass != cLong || OpNum < 2) {
    // Handle normal comparisons with a setcc instruction...
    BMI(MBB, IP, SetCCOpcodeTab[isSigned][OpNum], 0, TargetReg);
  } else {
    // Handle long comparisons by copying the value which is already in BL into
    // the register we want...
    BMI(MBB, IP, X86::MOVrr8, 1, TargetReg).addReg(X86::BL);
Brian Gaeke's avatar
Brian Gaeke committed
/// promote32 - Emit instructions to turn a narrow operand into a 32-bit-wide
/// operand, in the specified target register.
void ISel::promote32(unsigned targetReg, const ValueRecord &VR) {
  bool isUnsigned = VR.Ty->isUnsigned();

  // Make sure we have the register number for this value...
  unsigned Reg = VR.Val ? getReg(VR.Val) : VR.Reg;

  switch (getClassB(VR.Ty)) {
Chris Lattner's avatar
Chris Lattner committed
  case cByte:
    // Extend value into target register (8->32)
    if (isUnsigned)
      BuildMI(BB, X86::MOVZXr32r8, 1, targetReg).addReg(Reg);
Chris Lattner's avatar
Chris Lattner committed
    else
      BuildMI(BB, X86::MOVSXr32r8, 1, targetReg).addReg(Reg);
Chris Lattner's avatar
Chris Lattner committed
    break;
  case cShort:
    // Extend value into target register (16->32)
    if (isUnsigned)
      BuildMI(BB, X86::MOVZXr32r16, 1, targetReg).addReg(Reg);
Chris Lattner's avatar
Chris Lattner committed
    else
      BuildMI(BB, X86::MOVSXr32r16, 1, targetReg).addReg(Reg);
Chris Lattner's avatar
Chris Lattner committed
    break;
  case cInt:
    // Move value into target register (32->32)
    BuildMI(BB, X86::MOVrr32, 1, targetReg).addReg(Reg);
Chris Lattner's avatar
Chris Lattner committed
    break;
  default:
    assert(0 && "Unpromotable operand class in promote32");
  }
Brian Gaeke's avatar
Brian Gaeke committed
}
/// 'ret' instruction - Here we are interested in meeting the x86 ABI.  As such,
/// we have the following possibilities:
///
///   ret void: No return value, simply emit a 'ret' instruction
///   ret sbyte, ubyte : Extend value into EAX and return
///   ret short, ushort: Extend value into EAX and return
///   ret int, uint    : Move value into EAX and return
///   ret pointer      : Move value into EAX and return
Chris Lattner's avatar
Chris Lattner committed
///   ret long, ulong  : Move value into EAX/EDX and return
///   ret float/double : Top of FP stack
void ISel::visitReturnInst(ReturnInst &I) {
Chris Lattner's avatar
Chris Lattner committed
  if (I.getNumOperands() == 0) {
    BuildMI(BB, X86::RET, 0); // Just emit a 'ret' instruction
    return;
  }

  Value *RetVal = I.getOperand(0);
  unsigned RetReg = getReg(RetVal);
  switch (getClassB(RetVal->getType())) {
Chris Lattner's avatar
Chris Lattner committed
  case cByte:   // integral return values: extend or move into EAX and return
  case cShort:
  case cInt:
    promote32(X86::EAX, ValueRecord(RetReg, RetVal->getType()));
    BuildMI(BB, X86::IMPLICIT_USE, 2).addReg(X86::EAX).addReg(X86::ESP);
Chris Lattner's avatar
Chris Lattner committed
    break;
  case cFP:                   // Floats & Doubles: Return in ST(0)
    BuildMI(BB, X86::FpSETRESULT, 1).addReg(RetReg);
    // Declare that top-of-stack is live on exit
    BuildMI(BB, X86::IMPLICIT_USE, 2).addReg(X86::ST0).addReg(X86::ESP);
Chris Lattner's avatar
Chris Lattner committed
    break;
  case cLong:
    BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(RetReg);
    BuildMI(BB, X86::MOVrr32, 1, X86::EDX).addReg(RetReg+1);
    // Declare that EAX & EDX are live on exit
    BuildMI(BB, X86::IMPLICIT_USE, 3).addReg(X86::EAX).addReg(X86::EDX)
      .addReg(X86::ESP);
Chris Lattner's avatar
Chris Lattner committed
  default:
  // Emit a 'ret' instruction
Chris Lattner's avatar
Chris Lattner committed
  BuildMI(BB, X86::RET, 0);
// getBlockAfter - Return the basic block which occurs lexically after the
// specified one.
static inline BasicBlock *getBlockAfter(BasicBlock *BB) {
  Function::iterator I = BB; ++I;  // Get iterator to next block
  return I != BB->getParent()->end() ? &*I : 0;
}

/// visitBranchInst - Handle conditional and unconditional branches here.  Note
/// that since code layout is frozen at this point, that if we are trying to
/// jump to a block that is the immediate successor of the current block, we can
/// just make a fall-through (but we don't currently).
Chris Lattner's avatar
Chris Lattner committed
void ISel::visitBranchInst(BranchInst &BI) {
  BasicBlock *NextBB = getBlockAfter(BI.getParent());  // BB after current one

  if (!BI.isConditional()) {  // Unconditional branch?
    if (BI.getSuccessor(0) != NextBB)
      BuildMI(BB, X86::JMP, 1).addPCDisp(BI.getSuccessor(0));
    return;
  }

  // See if we can fold the setcc into the branch itself...
  SetCondInst *SCI = canFoldSetCCIntoBranch(BI.getCondition());
  if (SCI == 0) {
    // Nope, cannot fold setcc into this branch.  Emit a branch on a condition
    // computed some other way...
    unsigned condReg = getReg(BI.getCondition());
Chris Lattner's avatar
Chris Lattner committed
    BuildMI(BB, X86::CMPri8, 2).addReg(condReg).addZImm(0);
    if (BI.getSuccessor(1) == NextBB) {
      if (BI.getSuccessor(0) != NextBB)
        BuildMI(BB, X86::JNE, 1).addPCDisp(BI.getSuccessor(0));
    } else {
      BuildMI(BB, X86::JE, 1).addPCDisp(BI.getSuccessor(1));
      
      if (BI.getSuccessor(0) != NextBB)
        BuildMI(BB, X86::JMP, 1).addPCDisp(BI.getSuccessor(0));
    }

  unsigned OpNum = getSetCCNumber(SCI->getOpcode());
  MachineBasicBlock::iterator MII = BB->end();
  OpNum = EmitComparison(OpNum, SCI->getOperand(0), SCI->getOperand(1), BB,MII);

  const Type *CompTy = SCI->getOperand(0)->getType();
  bool isSigned = CompTy->isSigned() && getClassB(CompTy) != cFP;
  // LLVM  -> X86 signed  X86 unsigned
  // -----    ----------  ------------
  // seteq -> je          je
  // setne -> jne         jne
  // setlt -> jl          jb
  // setge -> jge         jae
  // setgt -> jg          ja
  // setle -> jle         jbe
  // ----
  //          js                  // Used by comparison with 0 optimization
  //          jns

  static const unsigned OpcodeTab[2][8] = {
    { X86::JE, X86::JNE, X86::JB, X86::JAE, X86::JA, X86::JBE, 0, 0 },
    { X86::JE, X86::JNE, X86::JL, X86::JGE, X86::JG, X86::JLE,
      X86::JS, X86::JNS },
  if (BI.getSuccessor(0) != NextBB) {
    BuildMI(BB, OpcodeTab[isSigned][OpNum], 1).addPCDisp(BI.getSuccessor(0));
    if (BI.getSuccessor(1) != NextBB)
      BuildMI(BB, X86::JMP, 1).addPCDisp(BI.getSuccessor(1));
  } else {
    // Change to the inverse condition...
    if (BI.getSuccessor(1) != NextBB) {
      OpNum ^= 1;
      BuildMI(BB, OpcodeTab[isSigned][OpNum], 1).addPCDisp(BI.getSuccessor(1));
    }
  }

/// doCall - This emits an abstract call instruction, setting up the arguments
/// and the return value as appropriate.  For the actual function call itself,
/// it inserts the specified CallMI instruction into the stream.
///
void ISel::doCall(const ValueRecord &Ret, MachineInstr *CallMI,
                  const std::vector<ValueRecord> &Args) {
  // Count how many bytes are to be pushed on the stack...
  unsigned NumBytes = 0;

  if (!Args.empty()) {
    for (unsigned i = 0, e = Args.size(); i != e; ++i)
      switch (getClassB(Args[i].Ty)) {
      case cByte: case cShort: case cInt:
        NumBytes += 4; break;
        NumBytes += 8; break;
        NumBytes += Args[i].Ty == Type::FloatTy ? 4 : 8;
        break;
      default: assert(0 && "Unknown class!");
      }

    // Adjust the stack pointer for the new arguments...
    BuildMI(BB, X86::ADJCALLSTACKDOWN, 1).addZImm(NumBytes);

    // Arguments go on the stack in reverse order, as specified by the ABI.
    unsigned ArgOffset = 0;
    for (unsigned i = 0, e = Args.size(); i != e; ++i) {
      unsigned ArgReg = Args[i].Val ? getReg(Args[i].Val) : Args[i].Reg;
      switch (getClassB(Args[i].Ty)) {
        // Promote arg to 32 bits wide into a temporary register...
        unsigned R = makeAnotherReg(Type::UIntTy);
        promote32(R, Args[i]);
        addRegOffset(BuildMI(BB, X86::MOVrm32, 5),
                     X86::ESP, ArgOffset).addReg(R);
        break;
        addRegOffset(BuildMI(BB, X86::MOVrm32, 5),
                     X86::ESP, ArgOffset).addReg(ArgReg);
        break;
        addRegOffset(BuildMI(BB, X86::MOVrm32, 5),
                     X86::ESP, ArgOffset).addReg(ArgReg);
        addRegOffset(BuildMI(BB, X86::MOVrm32, 5),
                     X86::ESP, ArgOffset+4).addReg(ArgReg+1);
        ArgOffset += 4;        // 8 byte entry, not 4.
        break;
        
        if (Args[i].Ty == Type::FloatTy) {
          addRegOffset(BuildMI(BB, X86::FSTr32, 5),
                       X86::ESP, ArgOffset).addReg(ArgReg);
        } else {
          assert(Args[i].Ty == Type::DoubleTy && "Unknown FP type!");
          addRegOffset(BuildMI(BB, X86::FSTr64, 5),
                       X86::ESP, ArgOffset).addReg(ArgReg);
          ArgOffset += 4;       // 8 byte entry, not 4.
        }
        break;
      default: assert(0 && "Unknown class!");