summaryrefslogtreecommitdiff
path: root/lib/Target/Hexagon/RDFGraph.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/Target/Hexagon/RDFGraph.cpp')
-rw-r--r--lib/Target/Hexagon/RDFGraph.cpp55
1 files changed, 35 insertions, 20 deletions
diff --git a/lib/Target/Hexagon/RDFGraph.cpp b/lib/Target/Hexagon/RDFGraph.cpp
index 9b47422153bb5..273d6b7cb0c8b 100644
--- a/lib/Target/Hexagon/RDFGraph.cpp
+++ b/lib/Target/Hexagon/RDFGraph.cpp
@@ -25,6 +25,7 @@ using namespace rdf;
// Printing functions. Have them here first, so that the rest of the code
// can use them.
+namespace llvm {
namespace rdf {
template<>
@@ -298,6 +299,7 @@ raw_ostream &operator<< (raw_ostream &OS,
}
} // namespace rdf
+} // namespace llvm
// Node allocation functions.
//
@@ -315,7 +317,7 @@ void NodeAllocator::startNewBlock() {
// Check if the block index is still within the allowed range, i.e. less
// than 2^N, where N is the number of bits in NodeId for the block index.
// BitsPerIndex is the number of bits per node index.
- assert((Blocks.size() < (1U << (8*sizeof(NodeId)-BitsPerIndex))) &&
+ assert((Blocks.size() < ((size_t)1 << (8*sizeof(NodeId)-BitsPerIndex))) &&
"Out of bits for block index");
ActiveEnd = P;
}
@@ -674,7 +676,7 @@ bool RegisterAliasInfo::alias(RegisterRef RA, RegisterRef RB) const {
// unchanged across this def.
bool TargetOperandInfo::isPreserving(const MachineInstr &In, unsigned OpNum)
const {
- return TII.isPredicated(&In);
+ return TII.isPredicated(In);
}
// Check if the definition of RR produces an unspecified value.
@@ -686,11 +688,17 @@ bool TargetOperandInfo::isClobbering(const MachineInstr &In, unsigned OpNum)
return false;
}
-// Check if the given instruction specifically requires
+// Check if the given instruction specifically requires
bool TargetOperandInfo::isFixedReg(const MachineInstr &In, unsigned OpNum)
const {
- if (In.isCall() || In.isReturn())
+ if (In.isCall() || In.isReturn() || In.isInlineAsm())
return true;
+ // Check for a tail call.
+ if (In.isBranch())
+ for (auto &O : In.operands())
+ if (O.isGlobal() || O.isSymbol())
+ return true;
+
const MCInstrDesc &D = In.getDesc();
if (!D.getImplicitDefs() && !D.getImplicitUses())
return false;
@@ -919,7 +927,7 @@ NodeAddr<FuncNode*> DataFlowGraph::newFunc(MachineFunction *MF) {
}
// Build the data flow graph.
-void DataFlowGraph::build() {
+void DataFlowGraph::build(unsigned Options) {
reset();
Func = newFunc(&MF);
@@ -964,7 +972,8 @@ void DataFlowGraph::build() {
linkBlockRefs(DM, EA);
// Finally, remove all unused phi nodes.
- removeUnusedPhis();
+ if (!(Options & BuildOptions::KeepDeadPhis))
+ removeUnusedPhis();
}
// For each stack in the map DefM, push the delimiter for block B on it.
@@ -1167,6 +1176,17 @@ NodeAddr<RefNode*> DataFlowGraph::getNextShadow(NodeAddr<InstrNode*> IA,
void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) {
auto SA = newStmt(BA, &In);
+ auto isCall = [] (const MachineInstr &In) -> bool {
+ if (In.isCall())
+ return true;
+ // Is tail call?
+ if (In.isBranch())
+ for (auto &Op : In.operands())
+ if (Op.isGlobal() || Op.isSymbol())
+ return true;
+ return false;
+ };
+
// Collect a set of registers that this instruction implicitly uses
// or defines. Implicit operands from an instruction will be ignored
// unless they are listed here.
@@ -1178,8 +1198,8 @@ void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) {
while (uint16_t R = *ImpU++)
ImpUses.insert({R, 0});
- bool IsCall = In.isCall(), IsReturn = In.isReturn();
- bool IsPredicated = TII.isPredicated(&In);
+ bool NeedsImplicit = isCall(In) || In.isInlineAsm() || In.isReturn();
+ bool IsPredicated = TII.isPredicated(In);
unsigned NumOps = In.getNumOperands();
// Avoid duplicate implicit defs. This will not detect cases of implicit
@@ -1212,7 +1232,7 @@ void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) {
if (!Op.isReg() || !Op.isDef() || !Op.isImplicit())
continue;
RegisterRef RR = { Op.getReg(), Op.getSubReg() };
- if (!IsCall && !ImpDefs.count(RR))
+ if (!NeedsImplicit && !ImpDefs.count(RR))
continue;
if (DoneDefs.count(RR))
continue;
@@ -1237,7 +1257,7 @@ void DataFlowGraph::buildStmt(NodeAddr<BlockNode*> BA, MachineInstr &In) {
// instructions regardless of whether or not they appear in the instruction
// descriptor's list.
bool Implicit = Op.isImplicit();
- bool TakeImplicit = IsReturn || IsCall || IsPredicated;
+ bool TakeImplicit = NeedsImplicit || IsPredicated;
if (Implicit && !TakeImplicit && !ImpUses.count(RR))
continue;
uint16_t Flags = NodeAttrs::None;
@@ -1456,9 +1476,9 @@ void DataFlowGraph::removeUnusedPhis() {
PhiQ.insert(OA.Id);
}
if (RA.Addr->isDef())
- unlinkDef(RA);
+ unlinkDef(RA, true);
else
- unlinkUse(RA);
+ unlinkUse(RA, true);
}
NodeAddr<BlockNode*> BA = PA.Addr->getOwner(*this);
BA.Addr->removeMember(PA, *this);
@@ -1546,6 +1566,7 @@ void DataFlowGraph::linkBlockRefs(DefStackMap &DefM, NodeAddr<BlockNode*> BA) {
// Push block delimiters.
markBlock(BA.Id, DefM);
+ assert(BA.Addr && "block node address is needed to create a data-flow link");
// For each non-phi instruction in the block, link all the defs and uses
// to their reaching defs. For any member of the block (including phis),
// push the defs on the corresponding stacks.
@@ -1593,13 +1614,10 @@ void DataFlowGraph::linkBlockRefs(DefStackMap &DefM, NodeAddr<BlockNode*> BA) {
}
// Remove the use node UA from any data-flow and structural links.
-void DataFlowGraph::unlinkUse(NodeAddr<UseNode*> UA) {
+void DataFlowGraph::unlinkUseDF(NodeAddr<UseNode*> UA) {
NodeId RD = UA.Addr->getReachingDef();
NodeId Sib = UA.Addr->getSibling();
- NodeAddr<InstrNode*> IA = UA.Addr->getOwner(*this);
- IA.Addr->removeMember(UA, *this);
-
if (RD == 0) {
assert(Sib == 0);
return;
@@ -1623,7 +1641,7 @@ void DataFlowGraph::unlinkUse(NodeAddr<UseNode*> UA) {
}
// Remove the def node DA from any data-flow and structural links.
-void DataFlowGraph::unlinkDef(NodeAddr<DefNode*> DA) {
+void DataFlowGraph::unlinkDefDF(NodeAddr<DefNode*> DA) {
//
// RD
// | reached
@@ -1710,7 +1728,4 @@ void DataFlowGraph::unlinkDef(NodeAddr<DefNode*> DA) {
Last.Addr->setSibling(RDA.Addr->getReachedUse());
RDA.Addr->setReachedUse(ReachedUses.front().Id);
}
-
- NodeAddr<InstrNode*> IA = DA.Addr->getOwner(*this);
- IA.Addr->removeMember(DA, *this);
}