SystemZISelDAGToDAG.cpp revision 961bb6f43026964004c0b811bd19fdf1735db5bc
1//==-- SystemZISelDAGToDAG.cpp - A dag to dag inst selector for SystemZ ---===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file defines an instruction selector for the SystemZ target. 11// 12//===----------------------------------------------------------------------===// 13 14#include "SystemZ.h" 15#include "SystemZISelLowering.h" 16#include "SystemZTargetMachine.h" 17#include "llvm/DerivedTypes.h" 18#include "llvm/Function.h" 19#include "llvm/Intrinsics.h" 20#include "llvm/CallingConv.h" 21#include "llvm/Constants.h" 22#include "llvm/CodeGen/MachineFrameInfo.h" 23#include "llvm/CodeGen/MachineFunction.h" 24#include "llvm/CodeGen/MachineInstrBuilder.h" 25#include "llvm/CodeGen/MachineRegisterInfo.h" 26#include "llvm/CodeGen/SelectionDAG.h" 27#include "llvm/CodeGen/SelectionDAGISel.h" 28#include "llvm/Target/TargetLowering.h" 29#include "llvm/Support/Compiler.h" 30#include "llvm/Support/Debug.h" 31using namespace llvm; 32 33namespace { 34 /// SystemZRRIAddressMode - This corresponds to rriaddr, but uses SDValue's 35 /// instead of register numbers for the leaves of the matched tree. 36 struct SystemZRRIAddressMode { 37 enum { 38 RegBase, 39 FrameIndexBase 40 } BaseType; 41 42 struct { // This is really a union, discriminated by BaseType! 43 SDValue Reg; 44 int FrameIndex; 45 } Base; 46 47 SDValue IndexReg; 48 int32_t Disp; 49 50 SystemZRRIAddressMode() 51 : BaseType(RegBase), IndexReg(), Disp(0) { 52 } 53 54 void dump() { 55 cerr << "SystemZRRIAddressMode " << this << '\n'; 56 if (BaseType == RegBase) { 57 cerr << "Base.Reg "; 58 if (Base.Reg.getNode() != 0) Base.Reg.getNode()->dump(); 59 else cerr << "nul"; 60 cerr << '\n'; 61 } else { 62 cerr << " Base.FrameIndex " << Base.FrameIndex << '\n'; 63 } 64 cerr << "IndexReg "; 65 if (IndexReg.getNode() != 0) IndexReg.getNode()->dump(); 66 else cerr << "nul"; 67 cerr << " Disp " << Disp << '\n'; 68 } 69 }; 70} 71 72/// SystemZDAGToDAGISel - SystemZ specific code to select SystemZ machine 73/// instructions for SelectionDAG operations. 74/// 75namespace { 76 class SystemZDAGToDAGISel : public SelectionDAGISel { 77 SystemZTargetLowering &Lowering; 78 const SystemZSubtarget &Subtarget; 79 80 public: 81 SystemZDAGToDAGISel(SystemZTargetMachine &TM, CodeGenOpt::Level OptLevel) 82 : SelectionDAGISel(TM, OptLevel), 83 Lowering(*TM.getTargetLowering()), 84 Subtarget(*TM.getSubtargetImpl()) { } 85 86 virtual void InstructionSelect(); 87 88 virtual const char *getPassName() const { 89 return "SystemZ DAG->DAG Pattern Instruction Selection"; 90 } 91 92 /// getI16Imm - Return a target constant with the specified value, of type 93 /// i16. 94 inline SDValue getI16Imm(uint64_t Imm) { 95 return CurDAG->getTargetConstant(Imm, MVT::i16); 96 } 97 98 /// getI32Imm - Return a target constant with the specified value, of type 99 /// i32. 100 inline SDValue getI32Imm(uint64_t Imm) { 101 return CurDAG->getTargetConstant(Imm, MVT::i32); 102 } 103 104 // Include the pieces autogenerated from the target description. 105 #include "SystemZGenDAGISel.inc" 106 107 private: 108 bool SelectAddrRRI(SDValue Op, SDValue Addr, 109 SDValue &Base, SDValue &Index, SDValue &Disp); 110 SDNode *Select(SDValue Op); 111 bool SelectAddrRI(const SDValue& Op, SDValue& Addr, 112 SDValue &Base, SDValue &Disp); 113 bool MatchAddress(SDValue N, SystemZRRIAddressMode &AM, unsigned Depth = 0); 114 bool MatchAddressBase(SDValue N, SystemZRRIAddressMode &AM); 115 116 #ifndef NDEBUG 117 unsigned Indent; 118 #endif 119 }; 120} // end anonymous namespace 121 122/// createSystemZISelDag - This pass converts a legalized DAG into a 123/// SystemZ-specific DAG, ready for instruction scheduling. 124/// 125FunctionPass *llvm::createSystemZISelDag(SystemZTargetMachine &TM, 126 CodeGenOpt::Level OptLevel) { 127 return new SystemZDAGToDAGISel(TM, OptLevel); 128} 129 130/// isImmSExt20 - This method tests to see if the node is either a 32-bit 131/// or 64-bit immediate, and if the value can be accurately represented as a 132/// sign extension from a 20-bit value. If so, this returns true and the 133/// immediate. 134static bool isImmSExt20(int64_t Val, int32_t &Imm) { 135 if (Val >= -524288 && Val <= 524287) { 136 Imm = (int32_t)Val; 137 return true; 138 } 139 return false; 140} 141 142static bool isImmSExt20(SDNode *N, int32_t &Imm) { 143 if (N->getOpcode() != ISD::Constant) 144 return false; 145 146 return isImmSExt20(cast<ConstantSDNode>(N)->getSExtValue(), Imm); 147} 148 149static bool isImmSExt20(SDValue Op, int32_t &Imm) { 150 return isImmSExt20(Op.getNode(), Imm); 151} 152 153/// Returns true if the address can be represented by a base register plus 154/// a signed 20-bit displacement [r+imm]. 155bool SystemZDAGToDAGISel::SelectAddrRI(const SDValue& Op, SDValue& Addr, 156 SDValue &Base, SDValue &Disp) { 157 // FIXME dl should come from parent load or store, not from address 158 DebugLoc dl = Addr.getDebugLoc(); 159 MVT VT = Addr.getValueType(); 160 161 if (Addr.getOpcode() == ISD::ADD) { 162 int32_t Imm = 0; 163 if (isImmSExt20(Addr.getOperand(1), Imm)) { 164 Disp = CurDAG->getTargetConstant(Imm, MVT::i32); 165 if (FrameIndexSDNode *FI = 166 dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) { 167 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), VT); 168 } else { 169 Base = Addr.getOperand(0); 170 } 171 return true; // [r+i] 172 } 173 } else if (Addr.getOpcode() == ISD::OR) { 174 int32_t Imm = 0; 175 if (isImmSExt20(Addr.getOperand(1), Imm)) { 176 // If this is an or of disjoint bitfields, we can codegen this as an add 177 // (for better address arithmetic) if the LHS and RHS of the OR are 178 // provably disjoint. 179 APInt LHSKnownZero, LHSKnownOne; 180 CurDAG->ComputeMaskedBits(Addr.getOperand(0), 181 APInt::getAllOnesValue(Addr.getOperand(0) 182 .getValueSizeInBits()), 183 LHSKnownZero, LHSKnownOne); 184 185 if ((LHSKnownZero.getZExtValue()|~(uint64_t)Imm) == ~0ULL) { 186 // If all of the bits are known zero on the LHS or RHS, the add won't 187 // carry. 188 Base = Addr.getOperand(0); 189 Disp = CurDAG->getTargetConstant(Imm, MVT::i32); 190 return true; 191 } 192 } 193 } else if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr)) { 194 // Loading from a constant address. 195 196 // If this address fits entirely in a 20-bit sext immediate field, codegen 197 // this as "d(r0)" 198 int32_t Imm; 199 if (isImmSExt20(CN, Imm)) { 200 Disp = CurDAG->getTargetConstant(Imm, MVT::i32); 201 Base = CurDAG->getRegister(0, VT); 202 return true; 203 } 204 } 205 206 Disp = CurDAG->getTargetConstant(0, MVT::i32); 207 if (FrameIndexSDNode *FI = dyn_cast<FrameIndexSDNode>(Addr)) 208 Base = CurDAG->getTargetFrameIndex(FI->getIndex(), VT); 209 else 210 Base = Addr; 211 return true; // [r+0] 212} 213 214/// MatchAddress - Add the specified node to the specified addressing mode, 215/// returning true if it cannot be done. This just pattern matches for the 216/// addressing mode. 217bool SystemZDAGToDAGISel::MatchAddress(SDValue N, SystemZRRIAddressMode &AM, 218 unsigned Depth) { 219 DebugLoc dl = N.getDebugLoc(); 220 DOUT << "MatchAddress: "; DEBUG(AM.dump()); 221 // Limit recursion. 222 if (Depth > 5) 223 return MatchAddressBase(N, AM); 224 225 // FIXME: We can perform better here. If we have something like 226 // (shift (add A, imm), N), we can try to reassociate stuff and fold shift of 227 // imm into addressing mode. 228 switch (N.getOpcode()) { 229 default: break; 230 case ISD::Constant: { 231 uint64_t Val = cast<ConstantSDNode>(N)->getSExtValue(); 232 int32_t Imm; 233 if (isImmSExt20(AM.Disp + Val, Imm)) { 234 AM.Disp = Imm; 235 return false; 236 } 237 break; 238 } 239 240 case ISD::FrameIndex: 241 if (AM.BaseType == SystemZRRIAddressMode::RegBase 242 && AM.Base.Reg.getNode() == 0) { 243 AM.BaseType = SystemZRRIAddressMode::FrameIndexBase; 244 AM.Base.FrameIndex = cast<FrameIndexSDNode>(N)->getIndex(); 245 return false; 246 } 247 break; 248 249 case ISD::SUB: { 250 // Given A-B, if A can be completely folded into the address and 251 // the index field with the index field unused, use -B as the index. 252 // This is a win if a has multiple parts that can be folded into 253 // the address. Also, this saves a mov if the base register has 254 // other uses, since it avoids a two-address sub instruction, however 255 // it costs an additional mov if the index register has other uses. 256 257 // Test if the LHS of the sub can be folded. 258 SystemZRRIAddressMode Backup = AM; 259 if (MatchAddress(N.getNode()->getOperand(0), AM, Depth+1)) { 260 AM = Backup; 261 break; 262 } 263 // Test if the index field is free for use. 264 if (AM.IndexReg.getNode()) { 265 AM = Backup; 266 break; 267 } 268 269 // If the base is a register with multiple uses, this transformation may 270 // save a mov. Otherwise it's probably better not to do it. 271 if (AM.BaseType == SystemZRRIAddressMode::RegBase && 272 (!AM.Base.Reg.getNode() || AM.Base.Reg.getNode()->hasOneUse())) { 273 AM = Backup; 274 break; 275 } 276 277 // Ok, the transformation is legal and appears profitable. Go for it. 278 SDValue RHS = N.getNode()->getOperand(1); 279 SDValue Zero = CurDAG->getConstant(0, N.getValueType()); 280 SDValue Neg = CurDAG->getNode(ISD::SUB, dl, N.getValueType(), Zero, RHS); 281 AM.IndexReg = Neg; 282 283 // Insert the new nodes into the topological ordering. 284 if (Zero.getNode()->getNodeId() == -1 || 285 Zero.getNode()->getNodeId() > N.getNode()->getNodeId()) { 286 CurDAG->RepositionNode(N.getNode(), Zero.getNode()); 287 Zero.getNode()->setNodeId(N.getNode()->getNodeId()); 288 } 289 if (Neg.getNode()->getNodeId() == -1 || 290 Neg.getNode()->getNodeId() > N.getNode()->getNodeId()) { 291 CurDAG->RepositionNode(N.getNode(), Neg.getNode()); 292 Neg.getNode()->setNodeId(N.getNode()->getNodeId()); 293 } 294 return false; 295 } 296 297 case ISD::ADD: { 298 SystemZRRIAddressMode Backup = AM; 299 if (!MatchAddress(N.getNode()->getOperand(0), AM, Depth+1) && 300 !MatchAddress(N.getNode()->getOperand(1), AM, Depth+1)) 301 return false; 302 AM = Backup; 303 if (!MatchAddress(N.getNode()->getOperand(1), AM, Depth+1) && 304 !MatchAddress(N.getNode()->getOperand(0), AM, Depth+1)) 305 return false; 306 AM = Backup; 307 308 // If we couldn't fold both operands into the address at the same time, 309 // see if we can just put each operand into a register and fold at least 310 // the add. 311 if (AM.BaseType == SystemZRRIAddressMode::RegBase && 312 !AM.Base.Reg.getNode() && !AM.IndexReg.getNode()) { 313 AM.Base.Reg = N.getNode()->getOperand(0); 314 AM.IndexReg = N.getNode()->getOperand(1); 315 return false; 316 } 317 break; 318 } 319 320 case ISD::OR: 321 // Handle "X | C" as "X + C" iff X is known to have C bits clear. 322 if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(N.getOperand(1))) { 323 SystemZRRIAddressMode Backup = AM; 324 uint64_t Offset = CN->getSExtValue(); 325 int32_t Imm; 326 // Start with the LHS as an addr mode. 327 if (!MatchAddress(N.getOperand(0), AM, Depth+1) && 328 // The resultant disp must fit in 20-bits. 329 isImmSExt20(AM.Disp + Offset, Imm) && 330 // Check to see if the LHS & C is zero. 331 CurDAG->MaskedValueIsZero(N.getOperand(0), CN->getAPIntValue())) { 332 AM.Disp = Imm; 333 return false; 334 } 335 AM = Backup; 336 } 337 break; 338 } 339 340 return MatchAddressBase(N, AM); 341} 342 343/// MatchAddressBase - Helper for MatchAddress. Add the specified node to the 344/// specified addressing mode without any further recursion. 345bool SystemZDAGToDAGISel::MatchAddressBase(SDValue N, 346 SystemZRRIAddressMode &AM) { 347 // Is the base register already occupied? 348 if (AM.BaseType != SystemZRRIAddressMode::RegBase || AM.Base.Reg.getNode()) { 349 // If so, check to see if the scale index register is set. 350 if (AM.IndexReg.getNode() == 0) { 351 AM.IndexReg = N; 352 return false; 353 } 354 355 // Otherwise, we cannot select it. 356 return true; 357 } 358 359 // Default, generate it as a register. 360 AM.BaseType = SystemZRRIAddressMode::RegBase; 361 AM.Base.Reg = N; 362 return false; 363} 364 365/// Returns true if the address can be represented by a base register plus 366/// index register plus a signed 20-bit displacement [base + idx + imm]. 367bool SystemZDAGToDAGISel::SelectAddrRRI(SDValue Op, SDValue Addr, 368 SDValue &Base, SDValue &Index, SDValue &Disp) { 369 SystemZRRIAddressMode AM; 370 bool Done = false; 371 372 // FIXME: Should we better use lay instruction for non-single uses? 373 374 if (!Done && MatchAddress(Addr, AM)) 375 return false; 376 377 MVT VT = Addr.getValueType(); 378 if (AM.BaseType == SystemZRRIAddressMode::RegBase) { 379 if (!AM.Base.Reg.getNode()) 380 AM.Base.Reg = CurDAG->getRegister(0, VT); 381 } 382 383 if (!AM.IndexReg.getNode()) 384 AM.IndexReg = CurDAG->getRegister(0, VT); 385 386 if (AM.BaseType == SystemZRRIAddressMode::RegBase) 387 Base = AM.Base.Reg; 388 else 389 Base = CurDAG->getTargetFrameIndex(AM.Base.FrameIndex, TLI.getPointerTy()); 390 Index = AM.IndexReg; 391 Disp = Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32); 392 393 return true; 394} 395 396/// InstructionSelect - This callback is invoked by 397/// SelectionDAGISel when it has created a SelectionDAG for us to codegen. 398void SystemZDAGToDAGISel::InstructionSelect() { 399 DEBUG(BB->dump()); 400 401 // Codegen the basic block. 402#ifndef NDEBUG 403 DOUT << "===== Instruction selection begins:\n"; 404 Indent = 0; 405#endif 406 SelectRoot(*CurDAG); 407#ifndef NDEBUG 408 DOUT << "===== Instruction selection ends:\n"; 409#endif 410 411 CurDAG->RemoveDeadNodes(); 412} 413 414SDNode *SystemZDAGToDAGISel::Select(SDValue Op) { 415 SDNode *Node = Op.getNode(); 416 DebugLoc dl = Op.getDebugLoc(); 417 418 // Dump information about the Node being selected 419 #ifndef NDEBUG 420 DOUT << std::string(Indent, ' ') << "Selecting: "; 421 DEBUG(Node->dump(CurDAG)); 422 DOUT << "\n"; 423 Indent += 2; 424 #endif 425 426 // If we have a custom node, we already have selected! 427 if (Node->isMachineOpcode()) { 428 #ifndef NDEBUG 429 DOUT << std::string(Indent-2, ' ') << "== "; 430 DEBUG(Node->dump(CurDAG)); 431 DOUT << "\n"; 432 Indent -= 2; 433 #endif 434 return NULL; 435 } 436 437 // Select the default instruction 438 SDNode *ResNode = SelectCode(Op); 439 440 #ifndef NDEBUG 441 DOUT << std::string(Indent-2, ' ') << "=> "; 442 if (ResNode == NULL || ResNode == Op.getNode()) 443 DEBUG(Op.getNode()->dump(CurDAG)); 444 else 445 DEBUG(ResNode->dump(CurDAG)); 446 DOUT << "\n"; 447 Indent -= 2; 448 #endif 449 450 return ResNode; 451} 452