mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-02 07:11:49 +00:00
Initial target-independent CodeGen support for BlockAddresses.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@85556 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
parent
c24096559d
commit
8c2b52552c
@ -22,6 +22,7 @@
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
|
||||
namespace llvm {
|
||||
class BlockAddress;
|
||||
class GCStrategy;
|
||||
class Constant;
|
||||
class ConstantArray;
|
||||
@ -334,6 +335,12 @@ namespace llvm {
|
||||
/// block label.
|
||||
MCSymbol *GetMBBSymbol(unsigned MBBID) const;
|
||||
|
||||
/// GetBlockAddressSymbol - Return the MCSymbol used to satisfy BlockAddress
|
||||
/// uses of the specified basic block.
|
||||
MCSymbol *GetBlockAddressSymbol(const BlockAddress *BA) const;
|
||||
MCSymbol *GetBlockAddressSymbol(const Function *F,
|
||||
const BasicBlock *BB) const;
|
||||
|
||||
/// EmitBasicBlockStart - This method prints the label for the specified
|
||||
/// MachineBasicBlock, an alignment (if present) and a comment describing
|
||||
/// it if appropriate.
|
||||
|
@ -76,6 +76,10 @@ class MachineBasicBlock : public ilist_node<MachineBasicBlock> {
|
||||
/// exception handler.
|
||||
bool IsLandingPad;
|
||||
|
||||
/// AddressTaken - Indicate that this basic block is potentially the
|
||||
/// target of an indirect branch.
|
||||
bool AddressTaken;
|
||||
|
||||
// Intrusive list support
|
||||
MachineBasicBlock() {}
|
||||
|
||||
@ -92,6 +96,14 @@ public:
|
||||
///
|
||||
const BasicBlock *getBasicBlock() const { return BB; }
|
||||
|
||||
/// hasAddressTaken - Test whether this block is potentially the target
|
||||
/// of an indirect branch.
|
||||
bool hasAddressTaken() const { return AddressTaken; }
|
||||
|
||||
/// setHasAddressTaken - Set this block to reflect that it potentially
|
||||
/// is the target of an indirect branch.
|
||||
void setHasAddressTaken() { AddressTaken = true; }
|
||||
|
||||
/// getParent - Return the MachineFunction containing this basic block.
|
||||
///
|
||||
const MachineFunction *getParent() const { return xParent; }
|
||||
|
@ -326,6 +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 getCopyToReg(SDValue Chain, DebugLoc dl, unsigned Reg, SDValue N) {
|
||||
return getNode(ISD::CopyToReg, dl, MVT::Other, Chain,
|
||||
|
@ -97,7 +97,7 @@ namespace ISD {
|
||||
BasicBlock, VALUETYPE, CONDCODE, Register,
|
||||
Constant, ConstantFP,
|
||||
GlobalAddress, GlobalTLSAddress, FrameIndex,
|
||||
JumpTable, ConstantPool, ExternalSymbol,
|
||||
JumpTable, ConstantPool, ExternalSymbol, BlockAddress,
|
||||
|
||||
// The address of the GOT
|
||||
GLOBAL_OFFSET_TABLE,
|
||||
@ -146,6 +146,7 @@ namespace ISD {
|
||||
TargetJumpTable,
|
||||
TargetConstantPool,
|
||||
TargetExternalSymbol,
|
||||
TargetBlockAddress,
|
||||
|
||||
/// RESULT = INTRINSIC_WO_CHAIN(INTRINSICID, arg1, arg2, ...)
|
||||
/// This node represents a target intrinsic function with no side effects.
|
||||
@ -2026,11 +2027,27 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
class BlockAddressSDNode : public SDNode {
|
||||
BlockAddress *BA;
|
||||
friend class SelectionDAG;
|
||||
BlockAddressSDNode(unsigned NodeTy, DebugLoc dl, EVT VT, BlockAddress *ba)
|
||||
: SDNode(NodeTy, dl, getSDVTList(VT)), BA(ba) {
|
||||
}
|
||||
public:
|
||||
BlockAddress *getBlockAddress() const { return BA; }
|
||||
|
||||
static bool classof(const BlockAddressSDNode *) { return true; }
|
||||
static bool classof(const SDNode *N) {
|
||||
return N->getOpcode() == ISD::BlockAddress ||
|
||||
N->getOpcode() == ISD::TargetBlockAddress;
|
||||
}
|
||||
};
|
||||
|
||||
class LabelSDNode : public SDNode {
|
||||
SDUse Chain;
|
||||
unsigned LabelID;
|
||||
friend class SelectionDAG;
|
||||
LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id)
|
||||
LabelSDNode(unsigned NodeTy, DebugLoc dl, SDValue ch, unsigned id)
|
||||
: SDNode(NodeTy, dl, getSDVTList(MVT::Other)), LabelID(id) {
|
||||
InitOperands(&Chain, ch);
|
||||
}
|
||||
|
@ -269,6 +269,10 @@ def externalsym : SDNode<"ISD::ExternalSymbol", SDTPtrLeaf, [],
|
||||
"ExternalSymbolSDNode">;
|
||||
def texternalsym: SDNode<"ISD::TargetExternalSymbol", SDTPtrLeaf, [],
|
||||
"ExternalSymbolSDNode">;
|
||||
def blockaddress : SDNode<"ISD::BlockAddress", SDTPtrLeaf, [],
|
||||
"BlockAddressSDNode">;
|
||||
def tblockaddress: SDNode<"ISD::TargetBlockAddress", SDTPtrLeaf, [],
|
||||
"BlockAddressSDNode">;
|
||||
|
||||
def add : SDNode<"ISD::ADD" , SDTIntBinOp ,
|
||||
[SDNPCommutative, SDNPAssociative]>;
|
||||
|
@ -1613,6 +1613,22 @@ 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 Function *F,
|
||||
const BasicBlock *BB) const {
|
||||
assert(BB->hasName() &&
|
||||
"Address of anonymous basic block not supported yet!");
|
||||
|
||||
std::string Mangled =
|
||||
Mang->getMangledName(F, Mang->makeNameProper(BB->getName()).c_str(),
|
||||
/*ForcePrivate=*/true);
|
||||
|
||||
return OutContext.GetOrCreateSymbol(StringRef(Mangled));
|
||||
}
|
||||
|
||||
MCSymbol *AsmPrinter::GetMBBSymbol(unsigned MBBID) const {
|
||||
SmallString<60> Name;
|
||||
raw_svector_ostream(Name) << MAI->getPrivateGlobalPrefix() << "BB"
|
||||
@ -1629,6 +1645,17 @@ void AsmPrinter::EmitBasicBlockStart(const MachineBasicBlock *MBB) const {
|
||||
if (unsigned Align = MBB->getAlignment())
|
||||
EmitAlignment(Log2_32(Align));
|
||||
|
||||
if (MBB->hasAddressTaken()) {
|
||||
GetBlockAddressSymbol(MBB->getBasicBlock()->getParent(),
|
||||
MBB->getBasicBlock())->print(O, MAI);
|
||||
O << ':';
|
||||
if (VerboseAsm) {
|
||||
O.PadToColumn(MAI->getCommentColumn());
|
||||
O << MAI->getCommentString() << " Address Taken";
|
||||
}
|
||||
O << '\n';
|
||||
}
|
||||
|
||||
if (MBB->pred_empty() || MBB->isOnlyReachableByFallthrough()) {
|
||||
if (VerboseAsm)
|
||||
O << MAI->getCommentString() << " BB#" << MBB->getNumber() << ':';
|
||||
|
@ -24,7 +24,8 @@
|
||||
using namespace llvm;
|
||||
|
||||
MachineBasicBlock::MachineBasicBlock(MachineFunction &mf, const BasicBlock *bb)
|
||||
: BB(bb), Number(-1), xParent(&mf), Alignment(0), IsLandingPad(false) {
|
||||
: BB(bb), Number(-1), xParent(&mf), Alignment(0), IsLandingPad(false),
|
||||
AddressTaken(false) {
|
||||
Insts.Parent = this;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,7 @@
|
||||
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/Constants.h"
|
||||
#include "llvm/Function.h"
|
||||
#include "llvm/InlineAsm.h"
|
||||
#include "llvm/Value.h"
|
||||
#include "llvm/Assembly/Writer.h"
|
||||
@ -180,6 +181,8 @@ bool MachineOperand::isIdenticalTo(const MachineOperand &Other) const {
|
||||
case MachineOperand::MO_ExternalSymbol:
|
||||
return !strcmp(getSymbolName(), Other.getSymbolName()) &&
|
||||
getOffset() == Other.getOffset();
|
||||
case MachineOperand::MO_BlockAddress:
|
||||
return getBlockAddress() == Other.getBlockAddress();
|
||||
}
|
||||
}
|
||||
|
||||
@ -273,6 +276,13 @@ void MachineOperand::print(raw_ostream &OS, const TargetMachine *TM) const {
|
||||
if (getOffset()) OS << "+" << getOffset();
|
||||
OS << '>';
|
||||
break;
|
||||
case MachineOperand::MO_BlockAddress:
|
||||
OS << "<blockaddress: ";
|
||||
WriteAsOperand(OS, getBlockAddress()->getFunction(), /*PrintType=*/false);
|
||||
OS << ", ";
|
||||
WriteAsOperand(OS, getBlockAddress()->getBasicBlock(), /*PrintType=*/false);
|
||||
OS << '>';
|
||||
break;
|
||||
default:
|
||||
llvm_unreachable("Unrecognized operand type");
|
||||
}
|
||||
|
@ -349,6 +349,8 @@ void InstrEmitter::AddOperand(MachineInstr *MI, SDValue Op,
|
||||
} else if (ExternalSymbolSDNode *ES = dyn_cast<ExternalSymbolSDNode>(Op)) {
|
||||
MI->addOperand(MachineOperand::CreateES(ES->getSymbol(),
|
||||
ES->getTargetFlags()));
|
||||
} else if (BlockAddressSDNode *BA = dyn_cast<BlockAddressSDNode>(Op)) {
|
||||
MI->addOperand(MachineOperand::CreateBA(BA->getBlockAddress()));
|
||||
} else {
|
||||
assert(Op.getValueType() != MVT::Other &&
|
||||
Op.getValueType() != MVT::Flag &&
|
||||
|
@ -58,6 +58,7 @@ namespace llvm {
|
||||
if (isa<ConstantPoolSDNode>(Node)) return true;
|
||||
if (isa<JumpTableSDNode>(Node)) return true;
|
||||
if (isa<ExternalSymbolSDNode>(Node)) return true;
|
||||
if (isa<BlockAddressSDNode>(Node)) return true;
|
||||
if (Node->getOpcode() == ISD::EntryToken) return true;
|
||||
return false;
|
||||
}
|
||||
|
@ -460,6 +460,11 @@ static void AddNodeIDCustom(FoldingSetNodeID &ID, const SDNode *N) {
|
||||
ID.AddInteger(SVN->getMaskElt(i));
|
||||
break;
|
||||
}
|
||||
case ISD::TargetBlockAddress:
|
||||
case ISD::BlockAddress: {
|
||||
ID.AddPointer(cast<BlockAddressSDNode>(N));
|
||||
break;
|
||||
}
|
||||
} // end switch (N->getOpcode())
|
||||
}
|
||||
|
||||
@ -1317,6 +1322,23 @@ SDValue SelectionDAG::getLabel(unsigned Opcode, DebugLoc dl,
|
||||
return SDValue(N, 0);
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getBlockAddress(BlockAddress *BA, DebugLoc DL,
|
||||
bool isTarget) {
|
||||
unsigned Opc = isTarget ? ISD::TargetBlockAddress : ISD::BlockAddress;
|
||||
|
||||
FoldingSetNodeID ID;
|
||||
AddNodeIDNode(ID, Opc, getVTList(TLI.getPointerTy()), 0, 0);
|
||||
ID.AddPointer(BA);
|
||||
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);
|
||||
CSEMap.InsertNode(N, IP);
|
||||
AllNodes.push_back(N);
|
||||
return SDValue(N, 0);
|
||||
}
|
||||
|
||||
SDValue SelectionDAG::getSrcValue(const Value *V) {
|
||||
assert((!V || isa<PointerType>(V->getType())) &&
|
||||
"SrcValue is not a pointer?");
|
||||
@ -5400,6 +5422,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
case ISD::EH_RETURN: return "EH_RETURN";
|
||||
case ISD::ConstantPool: return "ConstantPool";
|
||||
case ISD::ExternalSymbol: return "ExternalSymbol";
|
||||
case ISD::BlockAddress: return "BlockAddress";
|
||||
case ISD::INTRINSIC_WO_CHAIN:
|
||||
case ISD::INTRINSIC_VOID:
|
||||
case ISD::INTRINSIC_W_CHAIN: {
|
||||
@ -5421,6 +5444,7 @@ std::string SDNode::getOperationName(const SelectionDAG *G) const {
|
||||
case ISD::TargetJumpTable: return "TargetJumpTable";
|
||||
case ISD::TargetConstantPool: return "TargetConstantPool";
|
||||
case ISD::TargetExternalSymbol: return "TargetExternalSymbol";
|
||||
case ISD::TargetBlockAddress: return "TargetBlockAddress";
|
||||
|
||||
case ISD::CopyToReg: return "CopyToReg";
|
||||
case ISD::CopyFromReg: return "CopyFromReg";
|
||||
@ -5778,6 +5802,13 @@ void SDNode::print_details(raw_ostream &OS, const SelectionDAG *G) const {
|
||||
OS << ">";
|
||||
} else if (const MemSDNode* M = dyn_cast<MemSDNode>(this)) {
|
||||
OS << "<" << *M->getMemOperand() << ">";
|
||||
} else if (const BlockAddressSDNode *BA =
|
||||
dyn_cast<BlockAddressSDNode>(this)) {
|
||||
OS << "<";
|
||||
WriteAsOperand(OS, BA->getBlockAddress()->getFunction(), false);
|
||||
OS << ", ";
|
||||
WriteAsOperand(OS, BA->getBlockAddress()->getBasicBlock(), false);
|
||||
OS << ">";
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -322,6 +322,12 @@ void FunctionLoweringInfo::set(Function &fn, MachineFunction &mf,
|
||||
MBBMap[BB] = MBB;
|
||||
MF->push_back(MBB);
|
||||
|
||||
// Transfer the address-taken flag. This is necessary because there could
|
||||
// be multiple MachineBasicBlocks corresponding to one BasicBlock, and only
|
||||
// the first one should be marked.
|
||||
if (BB->hasAddressTaken())
|
||||
MBB->setHasAddressTaken();
|
||||
|
||||
// Create Machine PHI nodes for LLVM PHI nodes, lowering them as
|
||||
// appropriate.
|
||||
PHINode *PN;
|
||||
@ -895,6 +901,9 @@ SDValue SelectionDAGLowering::getValue(const Value *V) {
|
||||
return DAG.getMergeValues(&Constants[0], NumElts, getCurDebugLoc());
|
||||
}
|
||||
|
||||
if (BlockAddress *BA = dyn_cast<BlockAddress>(C))
|
||||
return DAG.getBlockAddress(BA, getCurDebugLoc());
|
||||
|
||||
const VectorType *VecTy = cast<VectorType>(V->getType());
|
||||
unsigned NumElements = VecTy->getNumElements();
|
||||
|
||||
@ -5741,8 +5750,7 @@ void SelectionDAGLowering::CopyValueToVirtualRegister(Value *V, unsigned Reg) {
|
||||
|
||||
#include "llvm/CodeGen/SelectionDAGISel.h"
|
||||
|
||||
void SelectionDAGISel::
|
||||
LowerArguments(BasicBlock *LLVMBB) {
|
||||
void SelectionDAGISel::LowerArguments(BasicBlock *LLVMBB) {
|
||||
// If this is the entry block, emit arguments.
|
||||
Function &F = *LLVMBB->getParent();
|
||||
SelectionDAG &DAG = SDL->DAG;
|
||||
|
@ -1933,6 +1933,7 @@ void DAGISelEmitter::EmitInstructionSelector(raw_ostream &OS) {
|
||||
<< " case ISD::TargetConstantPool:\n"
|
||||
<< " case ISD::TargetFrameIndex:\n"
|
||||
<< " case ISD::TargetExternalSymbol:\n"
|
||||
<< " case ISD::TargetBlockAddress:\n"
|
||||
<< " case ISD::TargetJumpTable:\n"
|
||||
<< " case ISD::TargetGlobalTLSAddress:\n"
|
||||
<< " case ISD::TargetGlobalAddress:\n"
|
||||
|
Loading…
Reference in New Issue
Block a user