ARMISelDAGToDAG.cpp revision 06c1e7eacb11edd1671eabfc11291b7716be2608
1//===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file was developed by Chris Lattner and is distributed under 6// the University of Illinois Open Source License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines an instruction selector for the ARM target. 11// 12//===----------------------------------------------------------------------===// 13 14#include "ARM.h" 15#include "ARMTargetMachine.h" 16#include "llvm/CallingConv.h" 17#include "llvm/DerivedTypes.h" 18#include "llvm/Function.h" 19#include "llvm/Intrinsics.h" 20#include "llvm/CodeGen/MachineFrameInfo.h" 21#include "llvm/CodeGen/MachineFunction.h" 22#include "llvm/CodeGen/MachineInstrBuilder.h" 23#include "llvm/CodeGen/SelectionDAG.h" 24#include "llvm/CodeGen/SelectionDAGISel.h" 25#include "llvm/CodeGen/SSARegMap.h" 26#include "llvm/Target/TargetLowering.h" 27#include "llvm/Support/Debug.h" 28#include <iostream> 29#include <set> 30using namespace llvm; 31 32namespace { 33 class ARMTargetLowering : public TargetLowering { 34 public: 35 ARMTargetLowering(TargetMachine &TM); 36 virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); 37 virtual const char *getTargetNodeName(unsigned Opcode) const; 38 }; 39 40} 41 42ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) 43 : TargetLowering(TM) { 44 setOperationAction(ISD::RET, MVT::Other, Custom); 45 setOperationAction(ISD::GlobalAddress, MVT::i32, Custom); 46 setOperationAction(ISD::ConstantPool, MVT::i32, Custom); 47} 48 49namespace llvm { 50 namespace ARMISD { 51 enum NodeType { 52 // Start the numbering where the builting ops and target ops leave off. 53 FIRST_NUMBER = ISD::BUILTIN_OP_END+ARM::INSTRUCTION_LIST_END, 54 /// CALL - A direct function call. 55 CALL 56 }; 57 } 58} 59 60const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { 61 switch (Opcode) { 62 default: return 0; 63 case ARMISD::CALL: return "ARMISD::CALL"; 64 } 65} 66 67// This transforms a ISD::CALL node into a 68// callseq_star <- ARMISD:CALL <- callseq_end 69// chain 70static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { 71 SDOperand Chain = Op.getOperand(0); 72 unsigned CallConv = cast<ConstantSDNode>(Op.getOperand(1))->getValue(); 73 assert(CallConv == CallingConv::C && "unknown calling convention"); 74 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0; 75 assert(isVarArg == false && "VarArg not supported"); 76 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0; 77 assert(isTailCall == false && "tail call not supported"); 78 SDOperand Callee = Op.getOperand(4); 79 unsigned NumOps = (Op.getNumOperands() - 5) / 2; 80 81 // Count how many bytes are to be pushed on the stack. Initially 82 // only the link register. 83 unsigned NumBytes = 4; 84 85 assert(NumOps <= 4); //no args on the stack 86 87 // Adjust the stack pointer for the new arguments... 88 // These operations are automatically eliminated by the prolog/epilog pass 89 Chain = DAG.getCALLSEQ_START(Chain, 90 DAG.getConstant(NumBytes, MVT::i32)); 91 92 static const unsigned regs[] = { 93 ARM::R0, ARM::R1, ARM::R2, ARM::R3 94 }; 95 96 std::vector<std::pair<unsigned, SDOperand> > RegsToPass; 97 98 for (unsigned i = 0; i != NumOps; ++i) { 99 SDOperand Arg = Op.getOperand(5+2*i); 100 RegsToPass.push_back(std::make_pair(regs[i], Arg)); 101 } 102 103 // Build a sequence of copy-to-reg nodes chained together with token chain 104 // and flag operands which copy the outgoing args into the appropriate regs. 105 SDOperand InFlag; 106 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 107 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second, 108 InFlag); 109 InFlag = Chain.getValue(1); 110 } 111 112 std::vector<MVT::ValueType> NodeTys; 113 NodeTys.push_back(MVT::Other); // Returns a chain 114 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. 115 116 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every 117 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol 118 // node so that legalize doesn't hack it. 119 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 120 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), Callee.getValueType()); 121 122 // If this is a direct call, pass the chain and the callee. 123 assert (Callee.Val); 124 std::vector<SDOperand> Ops; 125 Ops.push_back(Chain); 126 Ops.push_back(Callee); 127 128 unsigned CallOpc = ARMISD::CALL; 129 if (InFlag.Val) 130 Ops.push_back(InFlag); 131 Chain = DAG.getNode(CallOpc, NodeTys, Ops); 132 InFlag = Chain.getValue(1); 133 134 std::vector<SDOperand> ResultVals; 135 NodeTys.clear(); 136 137 // If the call has results, copy the values out of the ret val registers. 138 switch (Op.Val->getValueType(0)) { 139 default: assert(0 && "Unexpected ret value!"); 140 case MVT::Other: 141 break; 142 case MVT::i32: 143 Chain = DAG.getCopyFromReg(Chain, ARM::R0, MVT::i32, InFlag).getValue(1); 144 ResultVals.push_back(Chain.getValue(0)); 145 NodeTys.push_back(MVT::i32); 146 } 147 148 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, 149 DAG.getConstant(NumBytes, MVT::i32)); 150 NodeTys.push_back(MVT::Other); 151 152 if (ResultVals.empty()) 153 return Chain; 154 155 ResultVals.push_back(Chain); 156 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, ResultVals); 157 return Res.getValue(Op.ResNo); 158} 159 160static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { 161 SDOperand Copy; 162 SDOperand Chain = Op.getOperand(0); 163 switch(Op.getNumOperands()) { 164 default: 165 assert(0 && "Do not know how to return this many arguments!"); 166 abort(); 167 case 1: { 168 SDOperand LR = DAG.getRegister(ARM::R14, MVT::i32); 169 return DAG.getNode(ISD::BRIND, MVT::Other, Chain, LR); 170 } 171 case 3: 172 Copy = DAG.getCopyToReg(Chain, ARM::R0, Op.getOperand(1), SDOperand()); 173 if (DAG.getMachineFunction().liveout_empty()) 174 DAG.getMachineFunction().addLiveOut(ARM::R0); 175 break; 176 } 177 178 SDOperand LR = DAG.getRegister(ARM::R14, MVT::i32); 179 180 //bug: the copy and branch should be linked with a flag so that the 181 //scheduller can't move an instruction that destroys R0 in between them 182 //return DAG.getNode(ISD::BRIND, MVT::Other, Copy, LR, Copy.getValue(1)); 183 184 return DAG.getNode(ISD::BRIND, MVT::Other, Copy, LR); 185} 186 187static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG, 188 unsigned ArgNo) { 189 MachineFunction &MF = DAG.getMachineFunction(); 190 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); 191 assert (ObjectVT == MVT::i32); 192 SDOperand Root = Op.getOperand(0); 193 SSARegMap *RegMap = MF.getSSARegMap(); 194 195 unsigned num_regs = 4; 196 static const unsigned REGS[] = { 197 ARM::R0, ARM::R1, ARM::R2, ARM::R3 198 }; 199 200 if(ArgNo < num_regs) { 201 unsigned VReg = RegMap->createVirtualRegister(&ARM::IntRegsRegClass); 202 MF.addLiveIn(REGS[ArgNo], VReg); 203 return DAG.getCopyFromReg(Root, VReg, MVT::i32); 204 } else { 205 // If the argument is actually used, emit a load from the right stack 206 // slot. 207 if (!Op.Val->hasNUsesOfValue(0, ArgNo)) { 208 unsigned ArgOffset = (ArgNo - num_regs) * 4; 209 210 MachineFrameInfo *MFI = MF.getFrameInfo(); 211 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; 212 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); 213 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); 214 return DAG.getLoad(ObjectVT, Root, FIN, 215 DAG.getSrcValue(NULL)); 216 } else { 217 // Don't emit a dead load. 218 return DAG.getNode(ISD::UNDEF, ObjectVT); 219 } 220 } 221} 222 223static SDOperand LowerConstantPool(SDOperand Op, SelectionDAG &DAG) { 224 MVT::ValueType PtrVT = Op.getValueType(); 225 ConstantPoolSDNode *CP = cast<ConstantPoolSDNode>(Op); 226 Constant *C = CP->get(); 227 SDOperand CPI = DAG.getTargetConstantPool(C, PtrVT, CP->getAlignment()); 228 229 return CPI; 230} 231 232static SDOperand LowerGlobalAddress(SDOperand Op, 233 SelectionDAG &DAG) { 234 GlobalValue *GV = cast<GlobalAddressSDNode>(Op)->getGlobal(); 235 SDOperand CPAddr = DAG.getConstantPool(GV, MVT::i32, 2); 236 return DAG.getLoad(MVT::i32, DAG.getEntryNode(), CPAddr, 237 DAG.getSrcValue(NULL)); 238} 239 240static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) { 241 std::vector<SDOperand> ArgValues; 242 SDOperand Root = Op.getOperand(0); 243 244 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) { 245 SDOperand ArgVal = LowerFORMAL_ARGUMENT(Op, DAG, ArgNo); 246 247 ArgValues.push_back(ArgVal); 248 } 249 250 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0; 251 assert(!isVarArg); 252 253 ArgValues.push_back(Root); 254 255 // Return the new list of results. 256 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(), 257 Op.Val->value_end()); 258 return DAG.getNode(ISD::MERGE_VALUES, RetVT, ArgValues); 259} 260 261SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { 262 switch (Op.getOpcode()) { 263 default: 264 assert(0 && "Should not custom lower this!"); 265 abort(); 266 case ISD::ConstantPool: 267 return LowerConstantPool(Op, DAG); 268 case ISD::GlobalAddress: 269 return LowerGlobalAddress(Op, DAG); 270 case ISD::FORMAL_ARGUMENTS: 271 return LowerFORMAL_ARGUMENTS(Op, DAG); 272 case ISD::CALL: 273 return LowerCALL(Op, DAG); 274 case ISD::RET: 275 return LowerRET(Op, DAG); 276 } 277} 278 279//===----------------------------------------------------------------------===// 280// Instruction Selector Implementation 281//===----------------------------------------------------------------------===// 282 283//===--------------------------------------------------------------------===// 284/// ARMDAGToDAGISel - ARM specific code to select ARM machine 285/// instructions for SelectionDAG operations. 286/// 287namespace { 288class ARMDAGToDAGISel : public SelectionDAGISel { 289 ARMTargetLowering Lowering; 290 291public: 292 ARMDAGToDAGISel(TargetMachine &TM) 293 : SelectionDAGISel(Lowering), Lowering(TM) { 294 } 295 296 void Select(SDOperand &Result, SDOperand Op); 297 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); 298 bool SelectAddrRegImm(SDOperand N, SDOperand &Offset, SDOperand &Base); 299 300 // Include the pieces autogenerated from the target description. 301#include "ARMGenDAGISel.inc" 302}; 303 304void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { 305 DEBUG(BB->dump()); 306 307 DAG.setRoot(SelectRoot(DAG.getRoot())); 308 CodeGenMap.clear(); 309 HandleMap.clear(); 310 ReplaceMap.clear(); 311 DAG.RemoveDeadNodes(); 312 313 ScheduleAndEmitDAG(DAG); 314} 315 316//register plus/minus 12 bit offset 317bool ARMDAGToDAGISel::SelectAddrRegImm(SDOperand N, SDOperand &Offset, 318 SDOperand &Base) { 319 Offset = CurDAG->getTargetConstant(0, MVT::i32); 320 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N)) { 321 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType()); 322 } 323 else 324 Base = N; 325 return true; //any address fits in a register 326} 327 328void ARMDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) { 329 SDNode *N = Op.Val; 330 331 switch (N->getOpcode()) { 332 default: 333 SelectCode(Result, Op); 334 break; 335 } 336} 337 338} // end anonymous namespace 339 340/// createARMISelDag - This pass converts a legalized DAG into a 341/// ARM-specific DAG, ready for instruction scheduling. 342/// 343FunctionPass *llvm::createARMISelDag(TargetMachine &TM) { 344 return new ARMDAGToDAGISel(TM); 345} 346