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
/// 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,
const BasicBlock *BB) const;
const BasicBlock *BB,
const char *Suffix = "") const;
/// EmitBasicBlockStart - This method prints the label for the specified
/// MachineBasicBlock, an alignment (if present) and a comment describing

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -1174,7 +1174,7 @@ SDValue PPCTargetLowering::LowerBlockAddress(SDValue Op, SelectionDAG &DAG) {
DebugLoc DL = Op.getDebugLoc();
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 Hi = DAG.getNode(PPCISD::Hi, 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");
}
/// LowerGlobalAddressOperand - Lower an MO_GlobalAddress operand to an
/// MCOperand.
MCSymbol *X86MCInstLower::
@ -231,6 +230,19 @@ GetConstantPoolIndexSymbol(const MachineOperand &MO) const {
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,
MCSymbol *Sym) const {
// 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));
break;
case MachineOperand::MO_BlockAddress:
MCOp = LowerSymbolOperand(MO, AsmPrinter.GetBlockAddressSymbol(
MO.getBlockAddress()));
MCOp = LowerSymbolOperand(MO, GetBlockAddressSymbol(MO));
break;
}

View File

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

View File

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

View File

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

View File

@ -28,6 +28,21 @@ using namespace llvm;
#include <intrin.h>
#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
/// current subtarget according to how we should reference it in a non-pcrel
/// context.

View File

@ -199,6 +199,11 @@ public:
unsigned char ClassifyGlobalReference(const GlobalValue *GV,
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
/// to immediate address.
bool IsLegalToCallImmediateAddr(const TargetMachine &TM) const;

View File

@ -295,7 +295,7 @@ LowerBlockAddress(SDValue Op, SelectionDAG &DAG)
DebugLoc DL = Op.getDebugLoc();
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);
}