LLVM API Documentation
00001 //===-- ARMISelDAGToDAG.cpp - A dag to dag inst selector for ARM ----------===// 00002 // 00003 // The LLVM Compiler Infrastructure 00004 // 00005 // This file was developed by Chris Lattner and is distributed under 00006 // the University of Illinois Open Source License. See LICENSE.TXT for details. 00007 // 00008 //===----------------------------------------------------------------------===// 00009 // 00010 // This file defines an instruction selector for the ARM target. 00011 // 00012 //===----------------------------------------------------------------------===// 00013 00014 #include "ARM.h" 00015 #include "ARMTargetMachine.h" 00016 #include "llvm/CallingConv.h" 00017 #include "llvm/DerivedTypes.h" 00018 #include "llvm/Function.h" 00019 #include "llvm/Intrinsics.h" 00020 #include "llvm/CodeGen/MachineFrameInfo.h" 00021 #include "llvm/CodeGen/MachineFunction.h" 00022 #include "llvm/CodeGen/MachineInstrBuilder.h" 00023 #include "llvm/CodeGen/SelectionDAG.h" 00024 #include "llvm/CodeGen/SelectionDAGISel.h" 00025 #include "llvm/CodeGen/SSARegMap.h" 00026 #include "llvm/Target/TargetLowering.h" 00027 #include "llvm/Support/Debug.h" 00028 #include <iostream> 00029 #include <set> 00030 using namespace llvm; 00031 00032 namespace { 00033 class ARMTargetLowering : public TargetLowering { 00034 public: 00035 ARMTargetLowering(TargetMachine &TM); 00036 virtual SDOperand LowerOperation(SDOperand Op, SelectionDAG &DAG); 00037 virtual const char *getTargetNodeName(unsigned Opcode) const; 00038 }; 00039 00040 } 00041 00042 ARMTargetLowering::ARMTargetLowering(TargetMachine &TM) 00043 : TargetLowering(TM) { 00044 setOperationAction(ISD::RET, MVT::Other, Custom); 00045 } 00046 00047 namespace llvm { 00048 namespace ARMISD { 00049 enum NodeType { 00050 // Start the numbering where the builting ops and target ops leave off. 00051 FIRST_NUMBER = ISD::BUILTIN_OP_END+ARM::INSTRUCTION_LIST_END, 00052 /// CALL - A direct function call. 00053 CALL 00054 }; 00055 } 00056 } 00057 00058 const char *ARMTargetLowering::getTargetNodeName(unsigned Opcode) const { 00059 switch (Opcode) { 00060 default: return 0; 00061 case ARMISD::CALL: return "ARMISD::CALL"; 00062 } 00063 } 00064 00065 // This transforms a ISD::CALL node into a 00066 // callseq_star <- ARMISD:CALL <- callseq_end 00067 // chain 00068 static SDOperand LowerCALL(SDOperand Op, SelectionDAG &DAG) { 00069 SDOperand Chain = Op.getOperand(0); 00070 unsigned CallConv = cast<ConstantSDNode>(Op.getOperand(1))->getValue(); 00071 assert(CallConv == CallingConv::C && "unknown calling convention"); 00072 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0; 00073 assert(isVarArg == false && "VarArg not supported"); 00074 bool isTailCall = cast<ConstantSDNode>(Op.getOperand(3))->getValue() != 0; 00075 assert(isTailCall == false && "tail call not supported"); 00076 SDOperand Callee = Op.getOperand(4); 00077 unsigned NumOps = (Op.getNumOperands() - 5) / 2; 00078 00079 // Count how many bytes are to be pushed on the stack. Initially 00080 // only the link register. 00081 unsigned NumBytes = 4; 00082 00083 assert(NumOps <= 4); //no args on the stack 00084 00085 // Adjust the stack pointer for the new arguments... 00086 // These operations are automatically eliminated by the prolog/epilog pass 00087 Chain = DAG.getCALLSEQ_START(Chain, 00088 DAG.getConstant(NumBytes, MVT::i32)); 00089 00090 static const unsigned regs[] = { 00091 ARM::R0, ARM::R1, ARM::R2, ARM::R3 00092 }; 00093 00094 std::vector<std::pair<unsigned, SDOperand> > RegsToPass; 00095 00096 for (unsigned i = 0; i != NumOps; ++i) { 00097 SDOperand Arg = Op.getOperand(5+2*i); 00098 RegsToPass.push_back(std::make_pair(regs[i], Arg)); 00099 } 00100 00101 // Build a sequence of copy-to-reg nodes chained together with token chain 00102 // and flag operands which copy the outgoing args into the appropriate regs. 00103 SDOperand InFlag; 00104 for (unsigned i = 0, e = RegsToPass.size(); i != e; ++i) { 00105 Chain = DAG.getCopyToReg(Chain, RegsToPass[i].first, RegsToPass[i].second, 00106 InFlag); 00107 InFlag = Chain.getValue(1); 00108 } 00109 00110 std::vector<MVT::ValueType> NodeTys; 00111 NodeTys.push_back(MVT::Other); // Returns a chain 00112 NodeTys.push_back(MVT::Flag); // Returns a flag for retval copy to use. 00113 00114 // If the callee is a GlobalAddress/ExternalSymbol node (quite common, every 00115 // direct call is) turn it into a TargetGlobalAddress/TargetExternalSymbol 00116 // node so that legalize doesn't hack it. 00117 if (GlobalAddressSDNode *G = dyn_cast<GlobalAddressSDNode>(Callee)) 00118 Callee = DAG.getTargetGlobalAddress(G->getGlobal(), Callee.getValueType()); 00119 00120 // If this is a direct call, pass the chain and the callee. 00121 assert (Callee.Val); 00122 std::vector<SDOperand> Ops; 00123 Ops.push_back(Chain); 00124 Ops.push_back(Callee); 00125 00126 unsigned CallOpc = ARMISD::CALL; 00127 if (InFlag.Val) 00128 Ops.push_back(InFlag); 00129 Chain = DAG.getNode(CallOpc, NodeTys, Ops); 00130 InFlag = Chain.getValue(1); 00131 00132 std::vector<SDOperand> ResultVals; 00133 NodeTys.clear(); 00134 00135 // If the call has results, copy the values out of the ret val registers. 00136 switch (Op.Val->getValueType(0)) { 00137 default: assert(0 && "Unexpected ret value!"); 00138 case MVT::Other: 00139 break; 00140 case MVT::i32: 00141 Chain = DAG.getCopyFromReg(Chain, ARM::R0, MVT::i32, InFlag).getValue(1); 00142 ResultVals.push_back(Chain.getValue(0)); 00143 NodeTys.push_back(MVT::i32); 00144 } 00145 00146 Chain = DAG.getNode(ISD::CALLSEQ_END, MVT::Other, Chain, 00147 DAG.getConstant(NumBytes, MVT::i32)); 00148 NodeTys.push_back(MVT::Other); 00149 00150 if (ResultVals.empty()) 00151 return Chain; 00152 00153 ResultVals.push_back(Chain); 00154 SDOperand Res = DAG.getNode(ISD::MERGE_VALUES, NodeTys, ResultVals); 00155 return Res.getValue(Op.ResNo); 00156 } 00157 00158 static SDOperand LowerRET(SDOperand Op, SelectionDAG &DAG) { 00159 SDOperand Copy; 00160 SDOperand Chain = Op.getOperand(0); 00161 switch(Op.getNumOperands()) { 00162 default: 00163 assert(0 && "Do not know how to return this many arguments!"); 00164 abort(); 00165 case 1: { 00166 SDOperand LR = DAG.getRegister(ARM::R14, MVT::i32); 00167 return DAG.getNode(ISD::BRIND, MVT::Other, Chain, LR); 00168 } 00169 case 3: 00170 Copy = DAG.getCopyToReg(Chain, ARM::R0, Op.getOperand(1), SDOperand()); 00171 if (DAG.getMachineFunction().liveout_empty()) 00172 DAG.getMachineFunction().addLiveOut(ARM::R0); 00173 break; 00174 } 00175 00176 SDOperand LR = DAG.getRegister(ARM::R14, MVT::i32); 00177 00178 //bug: the copy and branch should be linked with a flag so that the 00179 //scheduller can't move an instruction that destroys R0 in between them 00180 //return DAG.getNode(ISD::BRIND, MVT::Other, Copy, LR, Copy.getValue(1)); 00181 00182 return DAG.getNode(ISD::BRIND, MVT::Other, Copy, LR); 00183 } 00184 00185 static SDOperand LowerFORMAL_ARGUMENT(SDOperand Op, SelectionDAG &DAG, 00186 unsigned ArgNo) { 00187 MachineFunction &MF = DAG.getMachineFunction(); 00188 MVT::ValueType ObjectVT = Op.getValue(ArgNo).getValueType(); 00189 assert (ObjectVT == MVT::i32); 00190 SDOperand Root = Op.getOperand(0); 00191 SSARegMap *RegMap = MF.getSSARegMap(); 00192 00193 unsigned num_regs = 4; 00194 static const unsigned REGS[] = { 00195 ARM::R0, ARM::R1, ARM::R2, ARM::R3 00196 }; 00197 00198 if(ArgNo < num_regs) { 00199 unsigned VReg = RegMap->createVirtualRegister(&ARM::IntRegsRegClass); 00200 MF.addLiveIn(REGS[ArgNo], VReg); 00201 return DAG.getCopyFromReg(Root, VReg, MVT::i32); 00202 } else { 00203 // If the argument is actually used, emit a load from the right stack 00204 // slot. 00205 if (!Op.Val->hasNUsesOfValue(0, ArgNo)) { 00206 unsigned ArgOffset = (ArgNo - num_regs) * 4; 00207 00208 MachineFrameInfo *MFI = MF.getFrameInfo(); 00209 unsigned ObjSize = MVT::getSizeInBits(ObjectVT)/8; 00210 int FI = MFI->CreateFixedObject(ObjSize, ArgOffset); 00211 SDOperand FIN = DAG.getFrameIndex(FI, MVT::i32); 00212 return DAG.getLoad(ObjectVT, Root, FIN, 00213 DAG.getSrcValue(NULL)); 00214 } else { 00215 // Don't emit a dead load. 00216 return DAG.getNode(ISD::UNDEF, ObjectVT); 00217 } 00218 } 00219 } 00220 00221 static SDOperand LowerFORMAL_ARGUMENTS(SDOperand Op, SelectionDAG &DAG) { 00222 std::vector<SDOperand> ArgValues; 00223 SDOperand Root = Op.getOperand(0); 00224 00225 for (unsigned ArgNo = 0, e = Op.Val->getNumValues()-1; ArgNo != e; ++ArgNo) { 00226 SDOperand ArgVal = LowerFORMAL_ARGUMENT(Op, DAG, ArgNo); 00227 00228 ArgValues.push_back(ArgVal); 00229 } 00230 00231 bool isVarArg = cast<ConstantSDNode>(Op.getOperand(2))->getValue() != 0; 00232 assert(!isVarArg); 00233 00234 ArgValues.push_back(Root); 00235 00236 // Return the new list of results. 00237 std::vector<MVT::ValueType> RetVT(Op.Val->value_begin(), 00238 Op.Val->value_end()); 00239 return DAG.getNode(ISD::MERGE_VALUES, RetVT, ArgValues); 00240 } 00241 00242 SDOperand ARMTargetLowering::LowerOperation(SDOperand Op, SelectionDAG &DAG) { 00243 switch (Op.getOpcode()) { 00244 default: 00245 assert(0 && "Should not custom lower this!"); 00246 abort(); 00247 case ISD::FORMAL_ARGUMENTS: 00248 return LowerFORMAL_ARGUMENTS(Op, DAG); 00249 case ISD::CALL: 00250 return LowerCALL(Op, DAG); 00251 case ISD::RET: 00252 return LowerRET(Op, DAG); 00253 } 00254 } 00255 00256 //===----------------------------------------------------------------------===// 00257 // Instruction Selector Implementation 00258 //===----------------------------------------------------------------------===// 00259 00260 //===--------------------------------------------------------------------===// 00261 /// ARMDAGToDAGISel - ARM specific code to select ARM machine 00262 /// instructions for SelectionDAG operations. 00263 /// 00264 namespace { 00265 class ARMDAGToDAGISel : public SelectionDAGISel { 00266 ARMTargetLowering Lowering; 00267 00268 public: 00269 ARMDAGToDAGISel(TargetMachine &TM) 00270 : SelectionDAGISel(Lowering), Lowering(TM) { 00271 } 00272 00273 void Select(SDOperand &Result, SDOperand Op); 00274 virtual void InstructionSelectBasicBlock(SelectionDAG &DAG); 00275 bool SelectAddrRegImm(SDOperand N, SDOperand &Offset, SDOperand &Base); 00276 00277 // Include the pieces autogenerated from the target description. 00278 #include "ARMGenDAGISel.inc" 00279 }; 00280 00281 void ARMDAGToDAGISel::InstructionSelectBasicBlock(SelectionDAG &DAG) { 00282 DEBUG(BB->dump()); 00283 00284 DAG.setRoot(SelectRoot(DAG.getRoot())); 00285 assert(InFlightSet.empty() && "ISel InFlightSet has not been emptied!"); 00286 CodeGenMap.clear(); 00287 HandleMap.clear(); 00288 ReplaceMap.clear(); 00289 DAG.RemoveDeadNodes(); 00290 00291 ScheduleAndEmitDAG(DAG); 00292 } 00293 00294 //register plus/minus 12 bit offset 00295 bool ARMDAGToDAGISel::SelectAddrRegImm(SDOperand N, SDOperand &Offset, 00296 SDOperand &Base) { 00297 Offset = CurDAG->getTargetConstant(0, MVT::i32); 00298 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(N)) { 00299 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), N.getValueType()); 00300 } 00301 else 00302 Base = N; 00303 return true; //any address fits in a register 00304 } 00305 00306 void ARMDAGToDAGISel::Select(SDOperand &Result, SDOperand Op) { 00307 SDNode *N = Op.Val; 00308 00309 switch (N->getOpcode()) { 00310 default: 00311 SelectCode(Result, Op); 00312 break; 00313 } 00314 } 00315 00316 } // end anonymous namespace 00317 00318 /// createARMISelDag - This pass converts a legalized DAG into a 00319 /// ARM-specific DAG, ready for instruction scheduling. 00320 /// 00321 FunctionPass *llvm::createARMISelDag(TargetMachine &TM) { 00322 return new ARMDAGToDAGISel(TM); 00323 }