This appears to fix Bug 172 and does not break any other feature tests or
[oota-llvm.git] / lib / CodeGen / InstrSelection / InstrSelectionSupport.cpp
1 //===-- InstrSelectionSupport.cpp -----------------------------------------===//
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 // Target-independent instruction selection code.  See SparcInstrSelection.cpp
11 // for usage.
12 // 
13 //===----------------------------------------------------------------------===//
14
15 #include "llvm/CodeGen/InstrSelectionSupport.h"
16 #include "llvm/CodeGen/InstrSelection.h"
17 #include "llvm/CodeGen/MachineInstrAnnot.h"
18 #include "llvm/CodeGen/MachineCodeForInstruction.h"
19 #include "llvm/CodeGen/InstrForest.h"
20 #include "llvm/Target/TargetMachine.h"
21 #include "llvm/Target/TargetRegInfo.h"
22 #include "llvm/Target/TargetInstrInfo.h"
23 #include "llvm/Constants.h"
24 #include "llvm/BasicBlock.h"
25 #include "llvm/DerivedTypes.h"
26 #include "../../Target/Sparc/SparcInstrSelectionSupport.h"  // FIXME!
27
28 namespace llvm {
29
30 // Generate code to load the constant into a TmpInstruction (virtual reg) and
31 // returns the virtual register.
32 // 
33 static TmpInstruction*
34 InsertCodeToLoadConstant(Function *F,
35                          Value* opValue,
36                          Instruction* vmInstr,
37                          std::vector<MachineInstr*>& loadConstVec,
38                          TargetMachine& target)
39 {
40   // Create a tmp virtual register to hold the constant.
41   MachineCodeForInstruction &mcfi = MachineCodeForInstruction::get(vmInstr);
42   TmpInstruction* tmpReg = new TmpInstruction(mcfi, opValue);
43   
44   target.getInstrInfo().CreateCodeToLoadConst(target, F, opValue, tmpReg,
45                                               loadConstVec, mcfi);
46   
47   // Record the mapping from the tmp VM instruction to machine instruction.
48   // Do this for all machine instructions that were not mapped to any
49   // other temp values created by 
50   // tmpReg->addMachineInstruction(loadConstVec.back());
51   
52   return tmpReg;
53 }
54
55
56 MachineOperand::MachineOperandType
57 ChooseRegOrImmed(int64_t intValue,
58                  bool isSigned,
59                  MachineOpCode opCode,
60                  const TargetMachine& target,
61                  bool canUseImmed,
62                  unsigned int& getMachineRegNum,
63                  int64_t& getImmedValue)
64 {
65   MachineOperand::MachineOperandType opType=MachineOperand::MO_VirtualRegister;
66   getMachineRegNum = 0;
67   getImmedValue = 0;
68
69   if (canUseImmed &&
70       target.getInstrInfo().constantFitsInImmedField(opCode, intValue)) {
71       opType = isSigned? MachineOperand::MO_SignExtendedImmed
72                        : MachineOperand::MO_UnextendedImmed;
73       getImmedValue = intValue;
74   } else if (intValue == 0 && target.getRegInfo().getZeroRegNum() >= 0) {
75     opType = MachineOperand::MO_MachineRegister;
76     getMachineRegNum = target.getRegInfo().getZeroRegNum();
77   }
78
79   return opType;
80 }
81
82
83 MachineOperand::MachineOperandType
84 ChooseRegOrImmed(Value* val,
85                  MachineOpCode opCode,
86                  const TargetMachine& target,
87                  bool canUseImmed,
88                  unsigned int& getMachineRegNum,
89                  int64_t& getImmedValue)
90 {
91   getMachineRegNum = 0;
92   getImmedValue = 0;
93
94   // To use reg or immed, constant needs to be integer, bool, or a NULL pointer
95   // TargetInstrInfo::ConvertConstantToIntType() does the right conversions:
96   bool isValidConstant;
97   uint64_t valueToUse =
98     target.getInstrInfo().ConvertConstantToIntType(target, val, val->getType(),
99                                                    isValidConstant);
100   if (! isValidConstant)
101     return MachineOperand::MO_VirtualRegister;
102
103   // Now check if the constant value fits in the IMMED field.
104   // 
105   return ChooseRegOrImmed((int64_t) valueToUse, val->getType()->isSigned(),
106                           opCode, target, canUseImmed,
107                           getMachineRegNum, getImmedValue);
108 }
109
110 //---------------------------------------------------------------------------
111 // Function: FixConstantOperandsForInstr
112 // 
113 // Purpose:
114 // Special handling for constant operands of a machine instruction
115 // -- if the constant is 0, use the hardwired 0 register, if any;
116 // -- if the constant fits in the IMMEDIATE field, use that field;
117 // -- else create instructions to put the constant into a register, either
118 //    directly or by loading explicitly from the constant pool.
119 // 
120 // In the first 2 cases, the operand of `minstr' is modified in place.
121 // Returns a vector of machine instructions generated for operands that
122 // fall under case 3; these must be inserted before `minstr'.
123 //---------------------------------------------------------------------------
124
125 std::vector<MachineInstr*>
126 FixConstantOperandsForInstr(Instruction* vmInstr,
127                             MachineInstr* minstr,
128                             TargetMachine& target)
129 {
130   std::vector<MachineInstr*> MVec;
131   
132   MachineOpCode opCode = minstr->getOpCode();
133   const TargetInstrInfo& instrInfo = target.getInstrInfo();
134   int resultPos = instrInfo.getResultPos(opCode);
135   int immedPos = instrInfo.getImmedConstantPos(opCode);
136
137   Function *F = vmInstr->getParent()->getParent();
138
139   for (unsigned op=0; op < minstr->getNumOperands(); op++)
140     {
141       const MachineOperand& mop = minstr->getOperand(op);
142           
143       // Skip the result position, preallocated machine registers, or operands
144       // that cannot be constants (CC regs or PC-relative displacements)
145       if (resultPos == (int)op ||
146           mop.getType() == MachineOperand::MO_MachineRegister ||
147           mop.getType() == MachineOperand::MO_CCRegister ||
148           mop.getType() == MachineOperand::MO_PCRelativeDisp)
149         continue;
150
151       bool constantThatMustBeLoaded = false;
152       unsigned int machineRegNum = 0;
153       int64_t immedValue = 0;
154       Value* opValue = NULL;
155       MachineOperand::MachineOperandType opType =
156         MachineOperand::MO_VirtualRegister;
157
158       // Operand may be a virtual register or a compile-time constant
159       if (mop.getType() == MachineOperand::MO_VirtualRegister) {
160         assert(mop.getVRegValue() != NULL);
161         opValue = mop.getVRegValue();
162         if (Constant *opConst = dyn_cast<Constant>(opValue)) {
163           opType = ChooseRegOrImmed(opConst, opCode, target,
164                                     (immedPos == (int)op), machineRegNum,
165                                     immedValue);
166           if (opType == MachineOperand::MO_VirtualRegister)
167             constantThatMustBeLoaded = true;
168         }
169       } else {
170         //
171         // If the operand is from the constant pool, don't try to change it.
172         //
173         if (mop.getType() == MachineOperand::MO_ConstantPoolIndex) {
174           continue;
175         }
176         assert(mop.isImmediate());
177         bool isSigned = mop.getType() == MachineOperand::MO_SignExtendedImmed;
178
179         // Bit-selection flags indicate an instruction that is extracting
180         // bits from its operand so ignore this even if it is a big constant.
181         if (mop.opHiBits32() || mop.opLoBits32() ||
182             mop.opHiBits64() || mop.opLoBits64())
183           continue;
184
185         opType = ChooseRegOrImmed(mop.getImmedValue(), isSigned,
186                                   opCode, target, (immedPos == (int)op), 
187                                   machineRegNum, immedValue);
188
189         if (opType == MachineOperand::MO_SignExtendedImmed ||
190             opType == MachineOperand::MO_UnextendedImmed) {
191           // The optype is an immediate value
192           // This means we need to change the opcode, e.g. ADDr -> ADDi
193           unsigned newOpcode = convertOpcodeFromRegToImm(opCode);
194           minstr->setOpcode(newOpcode);
195         }
196
197         if (opType == mop.getType()) 
198           continue;           // no change: this is the most common case
199
200         if (opType == MachineOperand::MO_VirtualRegister) {
201           constantThatMustBeLoaded = true;
202           opValue = isSigned
203             ? (Value*)ConstantSInt::get(Type::LongTy, immedValue)
204             : (Value*)ConstantUInt::get(Type::ULongTy,(uint64_t)immedValue);
205         }
206       }
207
208       if (opType == MachineOperand::MO_MachineRegister)
209         minstr->SetMachineOperandReg(op, machineRegNum);
210       else if (opType == MachineOperand::MO_SignExtendedImmed ||
211                opType == MachineOperand::MO_UnextendedImmed) {
212         minstr->SetMachineOperandConst(op, opType, immedValue);
213         // The optype is or has become an immediate
214         // This means we need to change the opcode, e.g. ADDr -> ADDi
215         unsigned newOpcode = convertOpcodeFromRegToImm(opCode);
216         minstr->setOpcode(newOpcode);
217       } else if (constantThatMustBeLoaded ||
218                (opValue && isa<GlobalValue>(opValue)))
219         { // opValue is a constant that must be explicitly loaded into a reg
220           assert(opValue);
221           TmpInstruction* tmpReg = InsertCodeToLoadConstant(F, opValue, vmInstr,
222                                                             MVec, target);
223           minstr->SetMachineOperandVal(op, MachineOperand::MO_VirtualRegister,
224                                        tmpReg);
225         }
226     }
227   
228   // Also, check for implicit operands used by the machine instruction
229   // (no need to check those defined since they cannot be constants).
230   // These include:
231   // -- arguments to a Call
232   // -- return value of a Return
233   // Any such operand that is a constant value needs to be fixed also.
234   // The current instructions with implicit refs (viz., Call and Return)
235   // have no immediate fields, so the constant always needs to be loaded
236   // into a register.
237   // 
238   bool isCall = instrInfo.isCall(opCode);
239   unsigned lastCallArgNum = 0;          // unused if not a call
240   CallArgsDescriptor* argDesc = NULL;   // unused if not a call
241   if (isCall)
242     argDesc = CallArgsDescriptor::get(minstr);
243   
244   for (unsigned i=0, N=minstr->getNumImplicitRefs(); i < N; ++i)
245     if (isa<Constant>(minstr->getImplicitRef(i)) ||
246         isa<GlobalValue>(minstr->getImplicitRef(i)))
247       {
248         Value* oldVal = minstr->getImplicitRef(i);
249         TmpInstruction* tmpReg =
250           InsertCodeToLoadConstant(F, oldVal, vmInstr, MVec, target);
251         minstr->setImplicitRef(i, tmpReg);
252         
253         if (isCall) {
254           // find and replace the argument in the CallArgsDescriptor
255           unsigned i=lastCallArgNum;
256           while (argDesc->getArgInfo(i).getArgVal() != oldVal)
257             ++i;
258           assert(i < argDesc->getNumArgs() &&
259                  "Constant operands to a call *must* be in the arg list");
260           lastCallArgNum = i;
261           argDesc->getArgInfo(i).replaceArgVal(tmpReg);
262         }
263       }
264   
265   return MVec;
266 }
267
268 } // End llvm namespace