//===-- InstSelectSimple.cpp - A simple instruction selector for x86 ------===//
//
// This file defines a simple peephole instruction selector for the x86 platform
//
//===----------------------------------------------------------------------===//
#include "X86.h"
#include "X86InstrInfo.h"
#include "X86InstrBuilder.h"
#include "llvm/Function.h"
#include "llvm/iTerminators.h"
#include "llvm/iOperators.h"
#include "llvm/iOther.h"
#include "llvm/iPHINode.h"
#include "llvm/iMemory.h"
#include "llvm/Type.h"
#include "llvm/DerivedTypes.h"
#include "llvm/Constants.h"
#include "llvm/Pass.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Support/InstVisitor.h"
#include "llvm/Target/MRegisterInfo.h"
#include <map>
using namespace MOTy; // Get Use, Def, UseAndDef
/// 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.
inline static MachineInstrBuilder BMI(MachineBasicBlock *MBB,
MachineBasicBlock::iterator &I,
MachineOpCode Opcode,
unsigned NumOperands,
unsigned DestReg) {
assert(I >= MBB->begin() && I <= MBB->end() && "Bad iterator!");
MachineInstr *MI = new MachineInstr(Opcode, NumOperands+1, true, true);
I = ++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.
inline static MachineInstrBuilder BMI(MachineBasicBlock *MBB,
MachineBasicBlock::iterator &I,
MachineOpCode Opcode,
unsigned NumOperands) {
assert(I > MBB->begin() && I <= MBB->end() && "Bad iterator!");
MachineInstr *MI = new MachineInstr(Opcode, NumOperands, true, true);
I = ++MBB->insert(I, MI);
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
unsigned CurReg;
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;
ISel(TargetMachine &tm)
: TM(tm), F(0), BB(0), CurReg(MRegisterInfo::FirstVirtualRegister) {}
/// runOnFunction - Top level implementation of instruction selection for
/// the entire function.
///
bool runOnFunction(Function &Fn) {
F = &MachineFunction::construct(&Fn, TM);
for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
// Emit instructions to load the arguments... The function's arguments
// look like this:
//
// [EBP] -- copy of old EBP
// [EBP + 4] -- return address
// [EBP + 8] -- first argument (leftmost lexically)
//
// So we want to start with counter = 2.
//
BB = &F->front();
unsigned ArgOffset = 8;
for (Function::aiterator I = Fn.abegin(), E = Fn.aend(); I != E;
++I, ArgOffset += 4