mirror of
https://github.com/RPCSX/llvm.git
synced 2024-12-02 16:56:50 +00:00
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:
parent
b9e6b34e1e
commit
29cbade25a
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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) {
|
||||
|
@ -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());
|
||||
}
|
||||
|
@ -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 &&
|
||||
|
@ -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 << ']';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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:
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user