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 "X86InstrInfo.h"
#include "llvm/Constants.h"
#include "llvm/DerivedTypes.h"
#include "llvm/IntrinsicLowering.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"
#include "llvm/Target/MRegisterInfo.h"
#include "llvm/Target/TargetMachine.h"
Chris Lattner
committed
#include "llvm/Support/GetElementPtrTypeIterator.h"
#include "llvm/Support/CFG.h"
using namespace llvm;
//#define SMART_FP 1
/// BMI - A special BuildMI variant that takes an iterator to insert the
/// instruction at as well as a basic block. This is the version for when you
/// have a destination register in mind.
MachineBasicBlock::iterator I,
unsigned DestReg) {
MachineInstr *MI = new MachineInstr(Opcode, NumOperands+1, true, true);
MBB->insert(I, MI);
return MachineInstrBuilder(MI).addReg(DestReg, MOTy::Def);
}
/// BMI - A special BuildMI variant that takes an iterator to insert the
/// instruction at as well as a basic block.
MachineBasicBlock::iterator I,
MachineInstr *MI = new MachineInstr(Opcode, NumOperands, true, true);
MBB->insert(I, MI);
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
Chris Lattner
committed
int ReturnAddressIndex; // FrameIndex for the return address
std::map<Value*, unsigned> RegMap; // Mapping between Val's and SSA Regs
// MBBMap - Mapping between LLVM BB -> Machine BB
std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;
Chris Lattner
committed
ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {}
/// runOnFunction - Top level implementation of instruction selection for
/// the entire function.
///
bool runOnFunction(Function &Fn) {
// First pass over the function, lower any unknown intrinsic functions
// with the IntrinsicLowering class.
LowerUnknownIntrinsicFunctionCalls(Fn);
F = &MachineFunction::construct(&Fn, TM);
// Create all of the machine basic blocks for the function...
for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
Chris Lattner
committed
Chris Lattner
committed
// Set up a frame object for the return address. This is used by the
// llvm.returnaddress & llvm.frameaddress intrinisics.
ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4);
Chris Lattner
committed
// Copy incoming arguments off of the stack...
LoadArgumentsToVirtualRegs(Fn);
// Instruction select everything except PHI nodes
// Select the PHI nodes
SelectPHINodes();
// We always build a machine code representation for the function
return true;
virtual const char *getPassName() const {
return "X86 Simple Instruction Selection";
}
/// visitBasicBlock - This method is called when we are visiting a new basic
/// 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) {
/// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
/// function, lowering any calls to unknown intrinsic functions into the
/// equivalent LLVM code.
void LowerUnknownIntrinsicFunctionCalls(Function &F);
/// LoadArgumentsToVirtualRegs - Load all of the arguments to this function
/// from the stack into virtual registers.
///
void LoadArgumentsToVirtualRegs(Function &F);
/// 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.
//
// Control flow operators
void visitBranchInst(BranchInst &BI);
struct ValueRecord {
Value *Val;
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(Intrinsic::ID ID, CallInst &I);
// Arithmetic operators
void visitSimpleBinary(BinaryOperator &B, unsigned OpcodeClass);
void visitAdd(BinaryOperator &B) { visitSimpleBinary(B, 0); }
void visitSub(BinaryOperator &B) { visitSimpleBinary(B, 1); }
Chris Lattner
committed
void doMultiply(MachineBasicBlock *MBB, MachineBasicBlock::iterator &MBBI,
unsigned DestReg, const Type *DestTy,
unsigned Op0Reg, unsigned Op1Reg);
Chris Lattner
committed
void doMultiplyConst(MachineBasicBlock *MBB,
MachineBasicBlock::iterator &MBBI,
unsigned DestReg, const Type *DestTy,
unsigned Op0Reg, unsigned Op1Val);
void visitDiv(BinaryOperator &B) { visitDivRem(B); }
void visitRem(BinaryOperator &B) { visitDivRem(B); }
void visitDivRem(BinaryOperator &B);
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);
Chris Lattner
committed
unsigned EmitComparison(unsigned OpNum, Value *Op0, Value *Op1,
MachineBasicBlock *MBB,
MachineBasicBlock::iterator &MBBI);
// Memory Instructions
void visitLoadInst(LoadInst &I);
void visitStoreInst(StoreInst &I);
void visitGetElementPtrInst(GetElementPtrInst &I);
void visitAllocaInst(AllocaInst &I);
void visitMallocInst(MallocInst &I);
void visitFreeInst(FreeInst &I);
void visitShiftInst(ShiftInst &I);
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();
}
///
void promote32(unsigned targetReg, const ValueRecord &VR);
/// emitGEPOperation - Common code shared between visitGetElementPtrInst and
/// constant expression GEP support.
///
void emitGEPOperation(MachineBasicBlock *BB, MachineBasicBlock::iterator&IP,
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);
/// emitShiftOperation - Common code shared between visitShiftInst and
/// constant expression support.
void emitShiftOperation(MachineBasicBlock *MBB,
Value *Op, Value *ShiftAmount, bool isLeftShift,
const Type *ResultTy, unsigned DestReg);
/// copyConstantToRegister - Output the instructions required to put the
/// specified constant into the specified register.
///
Chris Lattner
committed
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);
/// 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
unsigned getReg(Value *V) {
// Just append to the end of the current bb.
MachineBasicBlock::iterator It = BB->end();
return getReg(V, BB, It);
}
if (Reg == 0) {
Reg = makeAnotherReg(V->getType());
RegMap[V] = Reg;
}
// If this operand is a constant, emit the code to copy the constant into
// the register here...
//
if (Constant *C = dyn_cast<Constant>(V)) {
Chris Lattner
committed
copyConstantToRegister(MBB, IPt, C, Reg);
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::MOVri32, 1, Reg).addGlobalAddress(GV);
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 {
/// 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::ShortTyID:
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
case Type::FloatTyID:
case Type::DoubleTyID: return cFP; // Floating Point is #3
case Type::LongTyID:
case Type::ULongTyID: return cLong; // Longs are class #4
default:
assert(0 && "Invalid type to getClass!");
}
}
// 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.
///
Chris Lattner
committed
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:
case Instruction::Cast:
emitCastOperation(MBB, IP, CE->getOperand(0), CE->getType(), R);
return;
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;
case Instruction::Shl:
case Instruction::Shr:
emitShiftOperation(MBB, IP, CE->getOperand(0), CE->getOperand(1),
CE->getOpcode() == Instruction::Shl, CE->getType(), R);
return;
default:
std::cerr << "Offending expr: " << C << "\n";
Chris Lattner
committed
assert(0 && "Constant expression not yet handled!\n");
if (C->getType()->isIntegral()) {
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::MOVri32, 1, R).addZImm(Val & 0xFFFFFFFF);
BMI(MBB, IP, X86::MOVri32, 1, R+1).addZImm(Val >> 32);
return;
}
assert(Class <= cInt && "Type not handled yet!");
static const unsigned IntegralOpcodeTab[] = {
X86::MOVri8, X86::MOVri16, X86::MOVri32
};
if (C->getType() == Type::BoolTy) {
BMI(MBB, IP, X86::MOVri8, 1, R).addZImm(C == ConstantBool::True);
} else {
ConstantInt *CI = cast<ConstantInt>(C);
BMI(MBB, IP, IntegralOpcodeTab[Class], 1, R).addZImm(CI->getRawValue());
}
} else if (ConstantFP *CFP = dyn_cast<ConstantFP>(C)) {
Chris Lattner
committed
if (CFP->isExactlyValue(+0.0))
Chris Lattner
committed
else if (CFP->isExactlyValue(+1.0))
// 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);
BMI(MBB, IP, X86::MOVri32, 1, R).addZImm(0);
} else if (ConstantPointerRef *CPR = dyn_cast<ConstantPointerRef>(C)) {
} else {
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);
Chris Lattner
committed
addFrameReference(BuildMI(BB, X86::MOVrm8, 4, Reg), FI);
break;
case cShort:
FI = MFI->CreateFixedObject(2, ArgOffset);
Chris Lattner
committed
addFrameReference(BuildMI(BB, X86::MOVrm16, 4, Reg), FI);
break;
case cInt:
FI = MFI->CreateFixedObject(4, ArgOffset);
Chris Lattner
committed
addFrameReference(BuildMI(BB, X86::MOVrm32, 4, Reg), FI);
break;
case cLong:
FI = MFI->CreateFixedObject(8, ArgOffset);
Chris Lattner
committed
addFrameReference(BuildMI(BB, X86::MOVrm32, 4, Reg), FI);
addFrameReference(BuildMI(BB, X86::MOVrm32, 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);
} else {
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);
}
/// 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();
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...
MachineInstr* instr = MBB->begin();
for (BasicBlock::const_iterator I = BB->begin();
PHINode *PN = const_cast<PHINode*>(dyn_cast<PHINode>(I)); ++I) {
// Create a new machine instr PHI node, and insert it.
unsigned PHIReg = getReg(*PN);
MachineInstr *PhiMI = BuildMI(X86::PHI, PN->getNumOperands(), PHIReg);
MBB->insert(instr, PhiMI);
MachineInstr *LongPhiMI = 0;
if (PN->getType() == Type::LongTy || PN->getType() == Type::ULongTy) {
LongPhiMI = BuildMI(X86::PHI, PN->getNumOperands(), PHIReg+1);
MBB->insert(instr, 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;
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->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
// setgt -> setg seta
// setle -> setle setbe
Chris Lattner
committed
// ----
// 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 },
Chris Lattner
committed
// 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;
Chris Lattner
committed
// 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;
Chris Lattner
committed
static const unsigned CMPTab[] = {
X86::CMPri8, X86::CMPri16, X86::CMPri32
};
BMI(MBB, IP, CMPTab[Class], 2).addReg(Op0r).addZImm(Op1v);
return OpNum;
// Special case handling of comparison against +/- 0.0
if (ConstantFP *CFP = dyn_cast<ConstantFP>(Op1))
if (CFP->isExactlyValue(+0.0) || CFP->isExactlyValue(-0.0)) {
BMI(MBB, IP, X86::FTST, 1).addReg(Op0r);
BMI(MBB, IP, X86::FNSTSWr8, 0);
BMI(MBB, IP, X86::SAHF, 1);
return OpNum;
}
unsigned Op1r = getReg(Op1, MBB, IP);
default: assert(0 && "Unknown type class!");
// 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);
BMI(MBB, IP, X86::CMPrr16, 2).addReg(Op0r).addReg(Op1r);
BMI(MBB, IP, X86::CMPrr32, 2).addReg(Op0r).addReg(Op1r);
BMI(MBB, IP, X86::FpUCOM, 2).addReg(Op0r).addReg(Op1r);
BMI(MBB, IP, X86::FNSTSWr8, 0);
BMI(MBB, IP, X86::SAHF, 1);
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);
Chris Lattner
committed
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...
Chris Lattner
committed
return OpNum;
Chris Lattner
committed
return OpNum;
}
/// 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);
Chris Lattner
committed
OpNum = EmitComparison(OpNum, Op0, Op1, MBB, IP);
Chris Lattner
committed
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);
/// 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)) {
case cByte:
// Extend value into target register (8->32)
if (isUnsigned)
BuildMI(BB, X86::MOVZXr32r8, 1, targetReg).addReg(Reg);
BuildMI(BB, X86::MOVSXr32r8, 1, targetReg).addReg(Reg);
break;
case cShort:
// Extend value into target register (16->32)
if (isUnsigned)
BuildMI(BB, X86::MOVZXr32r16, 1, targetReg).addReg(Reg);
BuildMI(BB, X86::MOVSXr32r16, 1, targetReg).addReg(Reg);
break;
case cInt:
// Move value into target register (32->32)
BuildMI(BB, X86::MOVrr32, 1, targetReg).addReg(Reg);
break;
default:
assert(0 && "Unpromotable operand class in promote32");
}
/// '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
/// ret long, ulong : Move value into EAX/EDX and return
/// ret float/double : Top of FP stack
void ISel::visitReturnInst(ReturnInst &I) {
#ifndef SMART_FP
BuildMI(BB, X86::FP_REG_KILL, 0);
#endif
BuildMI(BB, X86::RET, 0); // Just emit a 'ret' instruction
return;
}
Value *RetVal = I.getOperand(0);
unsigned RetReg = getReg(RetVal);
switch (getClassB(RetVal->getType())) {
case cByte: // integral return values: extend or move into EAX and return
case cShort:
case cInt:
promote32(X86::EAX, ValueRecord(RetReg, RetVal->getType()));
Chris Lattner
committed
// Declare that EAX is live on exit
BuildMI(BB, X86::IMPLICIT_USE, 2).addReg(X86::EAX).addReg(X86::ESP);
break;
case cFP: // Floats & Doubles: Return in ST(0)
BuildMI(BB, X86::FpSETRESULT, 1).addReg(RetReg);
Chris Lattner
committed
// Declare that top-of-stack is live on exit
BuildMI(BB, X86::IMPLICIT_USE, 2).addReg(X86::ST0).addReg(X86::ESP);
BuildMI(BB, X86::MOVrr32, 1, X86::EAX).addReg(RetReg);
BuildMI(BB, X86::MOVrr32, 1, X86::EDX).addReg(RetReg+1);
Chris Lattner
committed
// Declare that EAX & EDX are live on exit
BuildMI(BB, X86::IMPLICIT_USE, 3).addReg(X86::EAX).addReg(X86::EDX)
.addReg(X86::ESP);
visitInstruction(I);
#ifndef SMART_FP
BuildMI(BB, X86::FP_REG_KILL, 0);
#endif
// 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;
}
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
/// RequiresFPRegKill - The floating point stackifier pass cannot insert
/// compensation code on critical edges. As such, it requires that we kill all
/// FP registers on the exit from any blocks that either ARE critical edges, or
/// branch to a block that has incoming critical edges.
///
/// Note that this kill instruction will eventually be eliminated when
/// restrictions in the stackifier are relaxed.
///
static bool RequiresFPRegKill(const BasicBlock *BB) {
#ifdef SMART_FP
for (succ_const_iterator SI = succ_begin(BB), E = succ_end(BB); SI!=E; ++SI) {
const BasicBlock *Succ = *SI;
pred_const_iterator PI = pred_begin(Succ), PE = pred_end(Succ);
++PI; // Block have at least one predecessory
if (PI != PE) { // If it has exactly one, this isn't crit edge
// If this block has more than one predecessor, check all of the
// predecessors to see if they have multiple successors. If so, then the
// block we are analyzing needs an FPRegKill.
for (PI = pred_begin(Succ); PI != PE; ++PI) {
const BasicBlock *Pred = *PI;
succ_const_iterator SI2 = succ_begin(Pred);
++SI2; // There must be at least one successor of this block.
if (SI2 != succ_end(Pred))
return true; // Yes, we must insert the kill on this edge.
}
}
}
// If we got this far, there is no need to insert the kill instruction.
return false;
#else
return true;
#endif
}
/// 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).
BasicBlock *NextBB = getBlockAfter(BI.getParent()); // BB after current one
if (!BI.isConditional()) { // Unconditional branch?
if (RequiresFPRegKill(BI.getParent()))
BuildMI(BB, X86::FP_REG_KILL, 0);
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());
BuildMI(BB, X86::CMPri8, 2).addReg(condReg).addZImm(0);
if (RequiresFPRegKill(BI.getParent()))
BuildMI(BB, X86::FP_REG_KILL, 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);
Chris Lattner
committed
const Type *CompTy = SCI->getOperand(0)->getType();
bool isSigned = CompTy->isSigned() && getClassB(CompTy) != cFP;
Chris Lattner
committed
// LLVM -> X86 signed X86 unsigned
// ----- ---------- ------------
// seteq -> je je
// setne -> jne jne
// setlt -> jl jb
// setgt -> jg ja
// setle -> jle jbe
Chris Lattner
committed
// ----
// 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,