llvm.org GIT mirror llvm / 6c7ccaa
Fix PR11985 - BlockAddress has no support of BA + offset form and there is no way to propagate that offset into machine operand; - Add BA + offset support and a new interface 'getTargetBlockAddress' to simplify target block address forming; - All targets are modified to use new interface and X86 backend is enhanced to support BA + offset addressing. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@163743 91177308-0d34-0410-b5e6-96231b3b80d8 Michael Liao 7 years ago
15 changed file(s) with 86 addition(s) and 35 deletion(s). Raw diff Collapse all Expand all
627627 Op.setTargetFlags(TargetFlags);
628628 return Op;
629629 }
630 static MachineOperand CreateBA(const BlockAddress *BA,
630 static MachineOperand CreateBA(const BlockAddress *BA, int64_t Offset,
631631 unsigned char TargetFlags = 0) {
632632 MachineOperand Op(MachineOperand::MO_BlockAddress);
633633 Op.Contents.OffsetedInfo.Val.BA = BA;
634 Op.setOffset(0); // Offset is always 0.
634 Op.setOffset(Offset);
635635 Op.setTargetFlags(TargetFlags);
636636 return Op;
637637 }
436436 SDValue getRegisterMask(const uint32_t *RegMask);
437437 SDValue getEHLabel(DebugLoc dl, SDValue Root, MCSymbol *Label);
438438 SDValue getBlockAddress(const BlockAddress *BA, EVT VT,
439 bool isTarget = false, unsigned char TargetFlags = 0);
439 int64_t Offset = 0, bool isTarget = false,
440 unsigned char TargetFlags = 0);
441 SDValue getTargetBlockAddress(const BlockAddress *BA, EVT VT,
442 int64_t Offset = 0,
443 unsigned char TargetFlags = 0) {
444 return getBlockAddress(BA, VT, Offset, true, TargetFlags);
445 }
440446
441447 SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
442448 return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
14821482
14831483 class BlockAddressSDNode : public SDNode {
14841484 const BlockAddress *BA;
1485 int64_t Offset;
14851486 unsigned char TargetFlags;
14861487 friend class SelectionDAG;
14871488 BlockAddressSDNode(unsigned NodeTy, EVT VT, const BlockAddress *ba,
1488 unsigned char Flags)
1489 int64_t o, unsigned char Flags)
14891490 : SDNode(NodeTy, DebugLoc(), getSDVTList(VT)),
1490 BA(ba), TargetFlags(Flags) {
1491 BA(ba), Offset(o), TargetFlags(Flags) {
14911492 }
14921493 public:
14931494 const BlockAddress *getBlockAddress() const { return BA; }
1495 int64_t getOffset() const { return Offset; }
14941496 unsigned char getTargetFlags() const { return TargetFlags; }
14951497
14961498 static bool classof(const BlockAddressSDNode *) { return true; }
197197 return !strcmp(getSymbolName(), Other.getSymbolName()) &&
198198 getOffset() == Other.getOffset();
199199 case MachineOperand::MO_BlockAddress:
200 return getBlockAddress() == Other.getBlockAddress();
200 return getBlockAddress() == Other.getBlockAddress() &&
201 getOffset() == Other.getOffset();
201202 case MO_RegisterMask:
202203 return getRegMask() == Other.getRegMask();
203204 case MachineOperand::MO_MCSymbol:
238239 MO.getOffset());
239240 case MachineOperand::MO_BlockAddress:
240241 return hash_combine(MO.getType(), MO.getTargetFlags(),
241 MO.getBlockAddress());
242 MO.getBlockAddress(), MO.getOffset());
242243 case MachineOperand::MO_RegisterMask:
243244 return hash_combine(MO.getType(), MO.getTargetFlags(), MO.getRegMask());
244245 case MachineOperand::MO_Metadata:
361362 case MachineOperand::MO_BlockAddress:
362363 OS << '<';
363364 WriteAsOperand(OS, getBlockAddress(), /*PrintType=*/false);
365 if (getOffset()) OS << "+" << getOffset();
364366 OS << '>';
365367 break;
366368 case MachineOperand::MO_RegisterMask:
409409 ES->getTargetFlags()));
410410 } else if (BlockAddressSDNode *BA = dyn_cast(Op)) {
411411 MI->addOperand(MachineOperand::CreateBA(BA->getBlockAddress(),
412 BA->getOffset(),
412413 BA->getTargetFlags()));
413414 } else if (TargetIndexSDNode *TI = dyn_cast(Op)) {
414415 MI->addOperand(MachineOperand::CreateTargetIndex(TI->getIndex(),
493493 }
494494 case ISD::TargetBlockAddress:
495495 case ISD::BlockAddress: {
496 ID.AddPointer(cast(N)->getBlockAddress());
497 ID.AddInteger(cast(N)->getTargetFlags());
496 const BlockAddressSDNode *BA = cast(N);
497 ID.AddPointer(BA->getBlockAddress());
498 ID.AddInteger(BA->getOffset());
499 ID.AddInteger(BA->getTargetFlags());
498500 break;
499501 }
500502 } // end switch (N->getOpcode())
14691471
14701472
14711473 SDValue SelectionDAG::getBlockAddress(const BlockAddress *BA, EVT VT,
1474 int64_t Offset,
14721475 bool isTarget,
14731476 unsigned char TargetFlags) {
14741477 unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress;
14761479 FoldingSetNodeID ID;
14771480 AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
14781481 ID.AddPointer(BA);
1482 ID.AddInteger(Offset);
14791483 ID.AddInteger(TargetFlags);
14801484 void *IP = 0;
14811485 if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
14821486 return SDValue(E, 0);
14831487
1484 SDNode *N = new (NodeAllocator) BlockAddressSDNode(Opc, VT, BA, TargetFlags);
1488 SDNode *N = new (NodeAllocator) BlockAddressSDNode(Opc, VT, BA, Offset,
1489 TargetFlags);
14851490 CSEMap.InsertNode(N, IP);
14861491 AllNodes.push_back(N);
14871492 return SDValue(N, 0);
474474 OS << "<" << *M->getMemOperand() << ">";
475475 } else if (const BlockAddressSDNode *BA =
476476 dyn_cast(this)) {
477 int64_t offset = BA->getOffset();
477478 OS << "<";
478479 WriteAsOperand(OS, BA->getBlockAddress()->getFunction(), false);
479480 OS << ", ";
480481 WriteAsOperand(OS, BA->getBlockAddress()->getBasicBlock(), false);
481482 OS << ">";
483 if (offset > 0)
484 OS << " + " << offset;
485 else
486 OS << " " << offset;
482487 if (unsigned int TF = BA->getTargetFlags())
483488 OS << " [TF=" << TF << ']';
484489 }
273273 else if (AM.JT != -1)
274274 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i16, 0/*AM.SymbolFlags*/);
275275 else if (AM.BlockAddr)
276 Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32,
277 true, 0/*AM.SymbolFlags*/);
276 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, 0,
277 0/*AM.SymbolFlags*/);
278278 else
279279 Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i16);
280280
654654 SelectionDAG &DAG) const {
655655 DebugLoc dl = Op.getDebugLoc();
656656 const BlockAddress *BA = cast(Op)->getBlockAddress();
657 SDValue Result = DAG.getBlockAddress(BA, getPointerTy(), /*isTarget=*/true);
657 SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy());
658658
659659 return DAG.getNode(MSP430ISD::Wrapper, dl, getPointerTy(), Result);
660660 }
16191619
16201620 if (getTargetMachine().getRelocationModel() != Reloc::PIC_ && !IsN64) {
16211621 // %hi/%lo relocation
1622 SDValue BAHi = DAG.getBlockAddress(BA, MVT::i32, true, MipsII::MO_ABS_HI);
1623 SDValue BALo = DAG.getBlockAddress(BA, MVT::i32, true, MipsII::MO_ABS_LO);
1622 SDValue BAHi = DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_HI);
1623 SDValue BALo = DAG.getTargetBlockAddress(BA, MVT::i32, 0, MipsII::MO_ABS_LO);
16241624 SDValue Hi = DAG.getNode(MipsISD::Hi, dl, MVT::i32, BAHi);
16251625 SDValue Lo = DAG.getNode(MipsISD::Lo, dl, MVT::i32, BALo);
16261626 return DAG.getNode(ISD::ADD, dl, MVT::i32, Hi, Lo);
16291629 EVT ValTy = Op.getValueType();
16301630 unsigned GOTFlag = HasMips64 ? MipsII::MO_GOT_PAGE : MipsII::MO_GOT;
16311631 unsigned OFSTFlag = HasMips64 ? MipsII::MO_GOT_OFST : MipsII::MO_ABS_LO;
1632 SDValue BAGOTOffset = DAG.getBlockAddress(BA, ValTy, true, GOTFlag);
1632 SDValue BAGOTOffset = DAG.getTargetBlockAddress(BA, ValTy, 0, GOTFlag);
16331633 BAGOTOffset = DAG.getNode(MipsISD::Wrapper, dl, ValTy,
16341634 GetGlobalReg(DAG, ValTy), BAGOTOffset);
1635 SDValue BALOOffset = DAG.getBlockAddress(BA, ValTy, true, OFSTFlag);
1635 SDValue BALOOffset = DAG.getTargetBlockAddress(BA, ValTy, 0, OFSTFlag);
16361636 SDValue Load = DAG.getLoad(ValTy, dl, DAG.getEntryNode(), BAGOTOffset,
16371637 MachinePointerInfo(), false, false, false, 0);
16381638 SDValue Lo = DAG.getNode(MipsISD::Lo, dl, ValTy, BALOOffset);
12631263
12641264 unsigned MOHiFlag, MOLoFlag;
12651265 bool isPIC = GetLabelAccessInfo(DAG.getTarget(), MOHiFlag, MOLoFlag);
1266 SDValue TgtBAHi = DAG.getBlockAddress(BA, PtrVT, /*isTarget=*/true, MOHiFlag);
1267 SDValue TgtBALo = DAG.getBlockAddress(BA, PtrVT, /*isTarget=*/true, MOLoFlag);
1266 SDValue TgtBAHi = DAG.getTargetBlockAddress(BA, PtrVT, 0, MOHiFlag);
1267 SDValue TgtBALo = DAG.getTargetBlockAddress(BA, PtrVT, 0, MOLoFlag);
12681268 return LowerLabelRef(TgtBAHi, TgtBALo, isPIC, DAG);
12691269 }
12701270
245245 else if (AM.CP)
246246 Disp = CurDAG->getTargetConstantPool(AM.CP, MVT::i32,
247247 AM.Align, AM.Disp, AM.SymbolFlags);
248 else if (AM.ES)
248 else if (AM.ES) {
249 assert(!AM.Disp && "Non-zero displacement is ignored with ES.");
249250 Disp = CurDAG->getTargetExternalSymbol(AM.ES, MVT::i32, AM.SymbolFlags);
250 else if (AM.JT != -1)
251 } else if (AM.JT != -1) {
252 assert(!AM.Disp && "Non-zero displacement is ignored with JT.");
251253 Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
252 else if (AM.BlockAddr)
253 Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32,
254 true, AM.SymbolFlags);
254 } else if (AM.BlockAddr)
255 Disp = CurDAG->getTargetBlockAddress(AM.BlockAddr, MVT::i32, AM.Disp,
256 AM.SymbolFlags);
255257 else
256258 Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
257259
653655 } else if (JumpTableSDNode *J = dyn_cast(N0)) {
654656 AM.JT = J->getIndex();
655657 AM.SymbolFlags = J->getTargetFlags();
656 } else {
657 AM.BlockAddr = cast(N0)->getBlockAddress();
658 AM.SymbolFlags = cast(N0)->getTargetFlags();
659 }
658 } else if (BlockAddressSDNode *BA = dyn_cast(N0)) {
659 X86ISelAddressMode Backup = AM;
660 AM.BlockAddr = BA->getBlockAddress();
661 AM.SymbolFlags = BA->getTargetFlags();
662 if (FoldOffsetIntoAddress(BA->getOffset(), AM)) {
663 AM = Backup;
664 return true;
665 }
666 } else
667 llvm_unreachable("Unhandled symbol reference node.");
660668
661669 if (N.getOpcode() == X86ISD::WrapperRIP)
662670 AM.setBaseReg(CurDAG->getRegister(X86::RIP, MVT::i64));
685693 } else if (JumpTableSDNode *J = dyn_cast(N0)) {
686694 AM.JT = J->getIndex();
687695 AM.SymbolFlags = J->getTargetFlags();
688 } else {
689 AM.BlockAddr = cast(N0)->getBlockAddress();
690 AM.SymbolFlags = cast(N0)->getTargetFlags();
691 }
696 } else if (BlockAddressSDNode *BA = dyn_cast(N0)) {
697 AM.BlockAddr = BA->getBlockAddress();
698 AM.Disp += BA->getOffset();
699 AM.SymbolFlags = BA->getTargetFlags();
700 } else
701 llvm_unreachable("Unhandled symbol reference node.");
692702 return false;
693703 }
694704
73677367 Subtarget->ClassifyBlockAddressReference();
73687368 CodeModel::Model M = getTargetMachine().getCodeModel();
73697369 const BlockAddress *BA = cast(Op)->getBlockAddress();
7370 int64_t Offset = cast(Op)->getOffset();
73707371 DebugLoc dl = Op.getDebugLoc();
7371 SDValue Result = DAG.getBlockAddress(BA, getPointerTy(),
7372 /*isTarget=*/true, OpFlags);
7372 SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy(), Offset,
7373 OpFlags);
73737374
73747375 if (Subtarget->isPICStyleRIPRel() &&
73757376 (M == CodeModel::Small || M == CodeModel::Kernel))
297297 DebugLoc DL = Op.getDebugLoc();
298298
299299 const BlockAddress *BA = cast(Op)->getBlockAddress();
300 SDValue Result = DAG.getBlockAddress(BA, getPointerTy(), /*isTarget=*/true);
300 SDValue Result = DAG.getTargetBlockAddress(BA, getPointerTy());
301301
302302 return DAG.getNode(XCoreISD::PCRelativeWrapper, DL, getPointerTy(), Result);
303303 }
0 ; RUN: llc < %s -mtriple=x86_64-pc-linux -mcpu=prescott | FileCheck %s
1
2 define float @foo(i8* nocapture %buf, float %a, float %b) nounwind uwtable {
3 entry:
4 tail call void @llvm.memcpy.p0i8.p0i8.i64(i8* %buf, i8* blockaddress(@foo, %out), i64 22, i32 1, i1 false)
5 br label %out
6
7 out: ; preds = %entry
8 %add = fadd float %a, %b
9 ret float %add
10 ; CHECK: foo
11 ; CHECK: movw .L{{.*}}+20(%rip), %{{.*}}
12 ; CHECK: movl .L{{.*}}+16(%rip), %{{.*}}
13 ; CHECK: movq .L{{.*}}+8(%rip), %{{.*}}
14 ; CHECK: movq .L{{.*}}(%rip), %{{.*}}
15 ; CHECK: ret
16 }
17
18 declare void @llvm.memcpy.p0i8.p0i8.i64(i8* nocapture, i8* nocapture, i64, i32, i1) nounwind