Add an instruction selector capable of selecting 'ret void'
[oota-llvm.git] / lib / Target / Sparc / InstSelectSimple.cpp
1 //===-- InstSelectSimple.cpp - A simple instruction selector for SparcV8 --===//
2 // 
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by the LLVM research group and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 // 
8 //===----------------------------------------------------------------------===//
9 //
10 // This file defines a simple peephole instruction selector for the V8 target
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "SparcV8.h"
15 #include "llvm/Instructions.h"
16 #include "llvm/IntrinsicLowering.h"
17 #include "llvm/Pass.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineFunction.h"
20 #include "llvm/Target/TargetMachine.h"
21 #include "llvm/Support/GetElementPtrTypeIterator.h"
22 #include "llvm/Support/InstVisitor.h"
23 #include "llvm/Support/CFG.h"
24 using namespace llvm;
25
26 namespace {
27   struct V8ISel : public FunctionPass, public InstVisitor<V8ISel> {
28     TargetMachine &TM;
29     MachineFunction *F;                 // The function we are compiling into
30     MachineBasicBlock *BB;              // The current MBB we are compiling
31
32     std::map<Value*, unsigned> RegMap;  // Mapping between Val's and SSA Regs
33
34     // MBBMap - Mapping between LLVM BB -> Machine BB
35     std::map<const BasicBlock*, MachineBasicBlock*> MBBMap;
36
37     V8ISel(TargetMachine &tm) : TM(tm), F(0), BB(0) {}
38
39     /// runOnFunction - Top level implementation of instruction selection for
40     /// the entire function.
41     ///
42     bool runOnFunction(Function &Fn);
43
44     virtual const char *getPassName() const {
45       return "SparcV8 Simple Instruction Selection";
46     }
47
48     /// visitBasicBlock - This method is called when we are visiting a new basic
49     /// block.  This simply creates a new MachineBasicBlock to emit code into
50     /// and adds it to the current MachineFunction.  Subsequent visit* for
51     /// instructions will be invoked for all instructions in the basic block.
52     ///
53     void visitBasicBlock(BasicBlock &LLVM_BB) {
54       BB = MBBMap[&LLVM_BB];
55     }
56
57     void visitReturnInst(ReturnInst &RI);
58
59     void visitInstruction(Instruction &I) {
60       std::cerr << "Unhandled instruction: " << I;
61       abort();
62     }
63
64     /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
65     /// function, lowering any calls to unknown intrinsic functions into the
66     /// equivalent LLVM code.
67     void LowerUnknownIntrinsicFunctionCalls(Function &F);
68
69
70     void visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI);
71
72   };
73 }
74
75 FunctionPass *llvm::createSparcV8SimpleInstructionSelector(TargetMachine &TM) {
76   return new V8ISel(TM);
77 }
78
79
80 bool V8ISel::runOnFunction(Function &Fn) {
81   // First pass over the function, lower any unknown intrinsic functions
82   // with the IntrinsicLowering class.
83   LowerUnknownIntrinsicFunctionCalls(Fn);
84   
85   F = &MachineFunction::construct(&Fn, TM);
86   
87   // Create all of the machine basic blocks for the function...
88   for (Function::iterator I = Fn.begin(), E = Fn.end(); I != E; ++I)
89     F->getBasicBlockList().push_back(MBBMap[I] = new MachineBasicBlock(I));
90   
91   BB = &F->front();
92   
93   // Set up a frame object for the return address.  This is used by the
94   // llvm.returnaddress & llvm.frameaddress intrinisics.
95   //ReturnAddressIndex = F->getFrameInfo()->CreateFixedObject(4, -4);
96   
97   // Copy incoming arguments off of the stack and out of fixed registers.
98   //LoadArgumentsToVirtualRegs(Fn);
99   
100   // Instruction select everything except PHI nodes
101   visit(Fn);
102   
103   // Select the PHI nodes
104   //SelectPHINodes();
105   
106   RegMap.clear();
107   MBBMap.clear();
108   F = 0;
109   // We always build a machine code representation for the function
110   return true;
111 }
112
113
114 void V8ISel::visitReturnInst(ReturnInst &I) {
115   if (I.getNumOperands() == 0) {
116     // Just emit a 'ret' instruction
117     BuildMI(BB, V8::JMPLi, 2, V8::G0).addZImm(8).addReg(V8::I7);
118     return;
119   }
120   visitInstruction(I);
121 }
122
123
124 /// LowerUnknownIntrinsicFunctionCalls - This performs a prepass over the
125 /// function, lowering any calls to unknown intrinsic functions into the
126 /// equivalent LLVM code.
127 void V8ISel::LowerUnknownIntrinsicFunctionCalls(Function &F) {
128   for (Function::iterator BB = F.begin(), E = F.end(); BB != E; ++BB)
129     for (BasicBlock::iterator I = BB->begin(), E = BB->end(); I != E; )
130       if (CallInst *CI = dyn_cast<CallInst>(I++))
131         if (Function *F = CI->getCalledFunction())
132           switch (F->getIntrinsicID()) {
133           case Intrinsic::not_intrinsic: break;
134           default:
135             // All other intrinsic calls we must lower.
136             Instruction *Before = CI->getPrev();
137             TM.getIntrinsicLowering().LowerIntrinsicCall(CI);
138             if (Before) {        // Move iterator to instruction after call
139               I = Before;  ++I;
140             } else {
141               I = BB->begin();
142             }
143           }
144 }
145
146
147 void V8ISel::visitIntrinsicCall(Intrinsic::ID ID, CallInst &CI) {
148   unsigned TmpReg1, TmpReg2;
149   switch (ID) {
150   default: assert(0 && "Intrinsic not supported!");
151   }
152 }