Target-independent support for TargetFlags on BlockAddress operands,

and support for blockaddresses in x86-32 PIC mode.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@89506 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Dan Gohman 2009-11-20 23:18:13 +00:00
parent b9e6b34e1e
commit 29cbade25a
16 changed files with 93 additions and 35 deletions

View File

@ -345,9 +345,11 @@ namespace llvm {
/// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress /// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress
/// uses of the specified basic block. /// uses of the specified basic block.
MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const; MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA,
const char *Suffix = "") const;
MCSymbol *GetBlockAddressSymbol(const Function *F, MCSymbol *GetBlockAddressSymbol(const Function *F,
const BasicBlock *BB) const; const BasicBlock *BB,
const char *Suffix = "") const;
/// EmitBasicBlockStart - This method prints the label for the specified /// EmitBasicBlockStart - This method prints the label for the specified
/// MachineBasicBlock, an alignment (if present) and a comment describing /// MachineBasicBlock, an alignment (if present) and a comment describing

View File

@ -435,10 +435,12 @@ public:
Op.setTargetFlags(TargetFlags); Op.setTargetFlags(TargetFlags);
return Op; return Op;
} }
static MachineOperand CreateBA(BlockAddress *BA) { static MachineOperand CreateBA(BlockAddress *BA,
unsigned char TargetFlags = 0) {
MachineOperand Op(MachineOperand::MO_BlockAddress); MachineOperand Op(MachineOperand::MO_BlockAddress);
Op.Contents.OffsetedInfo.Val.BA = BA; Op.Contents.OffsetedInfo.Val.BA = BA;
Op.setOffset(0); // Offset is always 0. Op.setOffset(0); // Offset is always 0.
Op.setTargetFlags(TargetFlags);
return Op; return Op;
} }

View File

@ -326,8 +326,8 @@ public:
unsigned Line, unsigned Col, MDNode *CU); unsigned Line, unsigned Col, MDNode *CU);
SDValue getLabel(unsigned Opcode, DebugLoc dl, SDValue Root, SDValue getLabel(unsigned Opcode, DebugLoc dl, SDValue Root,
unsigned LabelID); unsigned LabelID);
SDValue getBlockAddress(BlockAddress *BA, DebugLoc dl, SDValue getBlockAddress(BlockAddress *BA, EVT VT,
bool isTarget = false); bool isTarget = false, unsigned char TargetFlags = 0);
SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) { SDValue getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
return getNode(ISD::CopyToReg, dl, MVT::Other, Chain, return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,

View File

@ -2029,12 +2029,16 @@ public:
class BlockAddressSDNode : public SDNode { class BlockAddressSDNode : public SDNode {
BlockAddress *BA; BlockAddress *BA;
unsigned char TargetFlags;
friend class SelectionDAG; friend class SelectionDAG;
BlockAddressSDNode(unsigned NodeTy, DebugLoc dl, EVT VT, BlockAddress *ba) BlockAddressSDNode(unsigned NodeTy, EVT VT, BlockAddress *ba,
: SDNode(NodeTy, dl, getSDVTList(VT)), BA(ba) { unsigned char Flags)
: SDNode(NodeTy, DebugLoc::getUnknownLoc(), getSDVTList(VT)),
BA(ba), TargetFlags(Flags) {
} }
public: public:
BlockAddress *getBlockAddress() const { return BA; } BlockAddress *getBlockAddress() const { return BA; }
unsigned char getTargetFlags() const { return TargetFlags; }
static bool classof(const BlockAddressSDNode *) { return true; } static bool classof(const BlockAddressSDNode *) { return true; }
static bool classof(const SDNode *N) { static bool classof(const SDNode *N) {

View File

@ -1630,12 +1630,14 @@ bool AsmPrinter::PrintAsmMemoryOperand(const MachineInstr *MI, unsigned OpNo,
return true; return true;
} }
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA) const { MCSymbol *AsmPrinter::GetBlockAddressSymbol(const BlockAddress *BA,
return GetBlockAddressSymbol(BA->getFunction(), BA->getBasicBlock()); const char *Suffix) const {
return GetBlockAddressSymbol(BA->getFunction(), BA->getBasicBlock(), Suffix);
} }
MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F, MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F,
const BasicBlock *BB) const { const BasicBlock *BB,
const char *Suffix) const {
assert(BB->hasName() && assert(BB->hasName() &&
"Address of anonymous basic block not supported yet!"); "Address of anonymous basic block not supported yet!");
@ -1647,7 +1649,8 @@ MCSymbol *AsmPrinter::GetBlockAddressSymbol(const Function *F,
SmallString<60> Name; SmallString<60> Name;
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BA" raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BA"
<< FuncName.size() << '_' << FuncName << '_' << FuncName.size() << '_' << FuncName << '_'
<< Mang->makeNameProper(BB->getName()); << Mang->makeNameProper(BB->getName())
<< Suffix;
return OutContext.GetOrCreateSymbol(Name.str()); return OutContext.GetOrCreateSymbol(Name.str());
} }

View File

@ -350,7 +350,8 @@ void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op,
MI->addOperand(MachineOperand::CreateES(ES->getSymbol(), MI->addOperand(MachineOperand::CreateES(ES->getSymbol(),
ES->getTargetFlags())); ES->getTargetFlags()));
} else if (BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) { } else if (BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) {
MI->addOperand(MachineOperand::CreateBA(BA->getBlockAddress())); MI->addOperand(MachineOperand::CreateBA(BA->getBlockAddress(),
BA->getTargetFlags()));
} else { } else {
assert(Op.getValueType() != MVT::Other && assert(Op.getValueType() != MVT::Other &&
Op.getValueType() != MVT::Flag && Op.getValueType() != MVT::Flag &&

View File

@ -462,7 +462,8 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
} }
case ISD::TargetBlockAddress: case ISD::TargetBlockAddress:
case ISD::BlockAddress: { case ISD::BlockAddress: {
ID.AddPointer(cast<BlockAddressSDNode>(N)); ID.AddPointer(cast<BlockAddressSDNode>(N)->getBlockAddress());
ID.AddInteger(cast<BlockAddressSDNode>(N)->getTargetFlags());
break; break;
} }
} // end switch (N->getOpcode()) } // end switch (N->getOpcode())
@ -1323,18 +1324,20 @@ SDValue SelectionDAG::getLabel(unsigned Opcode, DebugLoc dl,
return SDValue(N, 0); return SDValue(N, 0);
} }
SDValue SelectionDAG::getBlockAddress(BlockAddress *BA, DebugLoc DL, SDValue SelectionDAG::getBlockAddress(BlockAddress *BA, EVT VT,
bool isTarget) { bool isTarget,
unsigned char TargetFlags) {
unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress; unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress;
FoldingSetNodeID ID; FoldingSetNodeID ID;
AddNodeIDNode(ID, Opc, getVTList(TLI.getPointerTy()), 0, 0); AddNodeIDNode(ID, Opc, getVTList(VT), 0, 0);
ID.AddPointer(BA); ID.AddPointer(BA);
ID.AddInteger(TargetFlags);
void *IP = 0; void *IP = 0;
if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP)) if (SDNode *E = CSEMap.FindNodeOrInsertPos(ID, IP))
return SDValue(E, 0); return SDValue(E, 0);
SDNode *N = NodeAllocator.Allocate<BlockAddressSDNode>(); SDNode *N = NodeAllocator.Allocate<BlockAddressSDNode>();
new (N) BlockAddressSDNode(Opc, DL, TLI.getPointerTy(), BA); new (N) BlockAddressSDNode(Opc, VT, BA, TargetFlags);
CSEMap.InsertNode(N, IP); CSEMap.InsertNode(N, IP);
AllNodes.push_back(N); AllNodes.push_back(N);
return SDValue(N, 0); return SDValue(N, 0);
@ -5810,6 +5813,8 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
OS << ", "; OS << ", ";
WriteAsOperand(OS, BA->getBlockAddress()->getBasicBlock(), false); WriteAsOperand(OS, BA->getBlockAddress()->getBasicBlock(), false);
OS << ">"; OS << ">";
if (unsigned int TF = BA->getTargetFlags())
OS << " [TF=" << TF << ']';
} }
} }

View File

@ -884,7 +884,7 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
} }
if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) if (BlockAddress *BA = dyn_cast<BlockAddress>(C))
return DAG.getBlockAddress(BA, getCurDebugLoc()); return DAG.getBlockAddress(BA, VT);
const VectorType *VecTy = cast<VectorType>(V->getType()); const VectorType *VecTy = cast<VectorType>(V->getType());
unsigned NumElements = VecTy->getNumElements(); unsigned NumElements = VecTy->getNumElements();

View File

@ -1174,7 +1174,7 @@ SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) {
DebugLoc DL = Op.getDebugLoc(); DebugLoc DL = Op.getDebugLoc();
BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
SDValue TgtBA = DAG.getBlockAddress(BA, DL, /*isTarget=*/true); SDValue TgtBA = DAG.getBlockAddress(BA, PtrVT, /*isTarget=*/true);
SDValue Zero = DAG.getConstant(0, PtrVT); SDValue Zero = DAG.getConstant(0, PtrVT);
SDValue Hi = DAG.getNode(PPCISD::Hi, DL, PtrVT, TgtBA, Zero); SDValue Hi = DAG.getNode(PPCISD::Hi, DL, PtrVT, TgtBA, Zero);
SDValue Lo = DAG.getNode(PPCISD::Lo, DL, PtrVT, TgtBA, Zero); SDValue Lo = DAG.getNode(PPCISD::Lo, DL, PtrVT, TgtBA, Zero);

View File

@ -43,7 +43,6 @@ MCSymbol *X86MCInstLower::GetPICBaseSymbol() const {
Twine(AsmPrinter.getFunctionNumber())+"$pb"); Twine(AsmPrinter.getFunctionNumber())+"$pb");
} }
/// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an /// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an
/// MCOperand. /// MCOperand.
MCSymbol *X86MCInstLower:: MCSymbol *X86MCInstLower::
@ -231,6 +230,19 @@ GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
return Ctx.GetOrCreateSymbol(Name.str()); return Ctx.GetOrCreateSymbol(Name.str());
} }
MCSymbol *X86MCInstLower::
GetBlockAddressSymbol(const MachineOperand &MO) const {
const char *Suffix = "";
switch (MO.getTargetFlags()) {
default: llvm_unreachable("Unknown target flag on BA operand");
case X86II::MO_NO_FLAG: // No flag.
case X86II::MO_PIC_BASE_OFFSET: // Doesn't modify symbol name.
case X86II::MO_GOTOFF: Suffix = "@GOTOFF"; break;
}
return AsmPrinter.GetBlockAddressSymbol(MO.getBlockAddress(), Suffix);
}
MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO, MCOperand X86MCInstLower::LowerSymbolOperand(const MachineOperand &MO,
MCSymbol *Sym) const { MCSymbol *Sym) const {
// FIXME: We would like an efficient form for this, so we don't have to do a // FIXME: We would like an efficient form for this, so we don't have to do a
@ -331,8 +343,7 @@ void X86MCInstLower::Lower(const MachineInstr *MI, MCInst &OutMI) const {
MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO)); MCOp = LowerSymbolOperand(MO, GetConstantPoolIndexSymbol(MO));
break; break;
case MachineOperand::MO_BlockAddress: case MachineOperand::MO_BlockAddress:
MCOp = LowerSymbolOperand(MO, AsmPrinter.GetBlockAddressSymbol( MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
MO.getBlockAddress()));
break; break;
} }

View File

@ -43,6 +43,7 @@ public:
MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const; MCSymbol *GetExternalSymbolSymbol(const MachineOperand &MO) const;
MCSymbol *GetJumpTableSymbol(const MachineOperand &MO) const; MCSymbol *GetJumpTableSymbol(const MachineOperand &MO) const;
MCSymbol *GetConstantPoolIndexSymbol(const MachineOperand &MO) const; MCSymbol *GetConstantPoolIndexSymbol(const MachineOperand &MO) const;
MCSymbol *GetBlockAddressSymbol(const MachineOperand &MO) const;
MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const; MCOperand LowerSymbolOperand(const MachineOperand &MO, MCSymbol *Sym) const;
private: private:

View File

@ -252,8 +252,8 @@ namespace {
else if (AM.JT != -1) else if (AM.JT != -1)
Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags); Disp = CurDAG->getTargetJumpTable(AM.JT, MVT::i32, AM.SymbolFlags);
else if (AM.BlockAddr) else if (AM.BlockAddr)
Disp = CurDAG->getBlockAddress(AM.BlockAddr, DebugLoc()/*MVT::i32*/, Disp = CurDAG->getBlockAddress(AM.BlockAddr, MVT::i32,
true /*AM.SymbolFlags*/); true, AM.SymbolFlags);
else else
Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32); Disp = CurDAG->getTargetConstant(AM.Disp, MVT::i32);
@ -777,7 +777,7 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {
AM.SymbolFlags = J->getTargetFlags(); AM.SymbolFlags = J->getTargetFlags();
} else { } else {
AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
//AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
} }
if (N.getOpcode() == X86ISD::WrapperRIP) if (N.getOpcode() == X86ISD::WrapperRIP)
@ -808,7 +808,7 @@ bool X86DAGToDAGISel::MatchWrapper(SDValue N, X86ISelAddressMode &AM) {
AM.SymbolFlags = J->getTargetFlags(); AM.SymbolFlags = J->getTargetFlags();
} else { } else {
AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress(); AM.BlockAddr = cast<BlockAddressSDNode>(N0)->getBlockAddress();
//AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags(); AM.SymbolFlags = cast<BlockAddressSDNode>(N0)->getTargetFlags();
} }
return false; return false;
} }

View File

@ -4722,18 +4722,27 @@ X86TargetLowering::LowerExternalSymbol(SDValue Op, SelectionDAG &DAG) {
SDValue SDValue
X86TargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) { X86TargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) {
unsigned WrapperKind = X86ISD::Wrapper; // Create the TargetBlockAddressAddress node.
unsigned char OpFlags =
Subtarget->ClassifyBlockAddressReference();
CodeModel::Model M = getTargetMachine().getCodeModel(); CodeModel::Model M = getTargetMachine().getCodeModel();
BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
DebugLoc dl = Op.getDebugLoc();
SDValue Result = DAG.getBlockAddress(BA, getPointerTy(),
/*isTarget=*/true, OpFlags);
if (Subtarget->isPICStyleRIPRel() && if (Subtarget->isPICStyleRIPRel() &&
(M == CodeModel::Small || M == CodeModel::Kernel)) (M == CodeModel::Small || M == CodeModel::Kernel))
WrapperKind = X86ISD::WrapperRIP; Result = DAG.getNode(X86ISD::WrapperRIP, dl, getPointerTy(), Result);
else
Result = DAG.getNode(X86ISD::Wrapper, dl, getPointerTy(), Result);
DebugLoc DL = Op.getDebugLoc(); // With PIC, the address is actually $g + Offset.
if (isGlobalRelativeToPICBase(OpFlags)) {
BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); Result = DAG.getNode(ISD::ADD, dl, getPointerTy(),
SDValue Result = DAG.getBlockAddress(BA, DL, /*isTarget=*/true); DAG.getNode(X86ISD::GlobalBaseReg, dl, getPointerTy()),
Result);
Result = DAG.getNode(WrapperKind, DL, getPointerTy(), Result); }
return Result; return Result;
} }

View File

@ -28,6 +28,21 @@ using namespace llvm;
#include <intrin.h> #include <intrin.h>
#endif #endif
/// ClassifyBlockAddressReference - Classify a blockaddress reference for the
/// current subtarget according to how we should reference it in a non-pcrel
/// context.
unsigned char X86Subtarget::
ClassifyBlockAddressReference() const {
if (isPICStyleGOT()) // 32-bit ELF targets.
return X86II::MO_GOTOFF;
if (isPICStyleStubPIC()) // Darwin/32 in PIC mode.
return X86II::MO_PIC_BASE_OFFSET;
// Direct static reference to label.
return X86II::MO_NO_FLAG;
}
/// ClassifyGlobalReference - Classify a global variable reference for the /// ClassifyGlobalReference - Classify a global variable reference for the
/// current subtarget according to how we should reference it in a non-pcrel /// current subtarget according to how we should reference it in a non-pcrel
/// context. /// context.

View File

@ -199,6 +199,11 @@ public:
unsigned char ClassifyGlobalReference(const GlobalValue *GV, unsigned char ClassifyGlobalReference(const GlobalValue *GV,
const TargetMachine &TM)const; const TargetMachine &TM)const;
/// ClassifyBlockAddressReference - Classify a blockaddress reference for the
/// current subtarget according to how we should reference it in a non-pcrel
/// context.
unsigned char ClassifyBlockAddressReference() const;
/// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls /// IsLegalToCallImmediateAddr - Return true if the subtarget allows calls
/// to immediate address. /// to immediate address.
bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const; bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const;

View File

@ -295,7 +295,7 @@ LowerBlockAddress(SDValue Op, SelectionDAG &DAG)
DebugLoc DL = Op.getDebugLoc(); DebugLoc DL = Op.getDebugLoc();
BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress(); BlockAddress *BA = cast<BlockAddressSDNode>(Op)->getBlockAddress();
SDValue Result = DAG.getBlockAddress(BA, DL, /*isTarget=*/true); SDValue Result = DAG.getBlockAddress(BA, getPointerTy(), /*isTarget=*/true);
return DAG.getNode(XCoreISD::PCRelativeWrapper, DL, getPointerTy(), Result); return DAG.getNode(XCoreISD::PCRelativeWrapper, DL, getPointerTy(), Result);
} }