forked from OSchip/llvm-project
Hexagon RDF: Replace function template (plus explicit specializations) with non-template overloads
For the design in question, overloads seem to be a much simpler and less subtle solution. This removes ODR issues, and errors of the kind where code that uses the specialization in question will accidentally and erroneously specialize the primary template. This only "works" by accident; the program is ill-formed NDR. (Found with -Wundefined-func-template.) Patch by Thomas Köppe! Differential Revision: https://reviews.llvm.org/D58998 llvm-svn: 355880
This commit is contained in:
parent
157d23f79e
commit
eae78b5157
|
@ -54,7 +54,6 @@ raw_ostream &operator<< (raw_ostream &OS, const PrintLaneMaskOpt &P) {
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterRef> &P) {
|
||||
auto &TRI = P.G.getTRI();
|
||||
if (P.Obj.Reg > 0 && P.Obj.Reg < TRI.getNumRegs())
|
||||
|
@ -65,7 +64,6 @@ raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterRef> &P) {
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<NodeId> &P) {
|
||||
auto NA = P.G.addr<NodeBase*>(P.Obj);
|
||||
uint16_t Attrs = NA.Addr->getAttrs();
|
||||
|
@ -115,7 +113,6 @@ static void printRefHeader(raw_ostream &OS, const NodeAddr<RefNode*> RA,
|
|||
OS << '!';
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<DefNode*>> &P) {
|
||||
printRefHeader(OS, P.Obj, P.G);
|
||||
OS << '(';
|
||||
|
@ -133,7 +130,6 @@ raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<DefNode*>> &P) {
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<UseNode*>> &P) {
|
||||
printRefHeader(OS, P.Obj, P.G);
|
||||
OS << '(';
|
||||
|
@ -145,7 +141,6 @@ raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<UseNode*>> &P) {
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS,
|
||||
const Print<NodeAddr<PhiUseNode*>> &P) {
|
||||
printRefHeader(OS, P.Obj, P.G);
|
||||
|
@ -161,7 +156,6 @@ raw_ostream &operator<< (raw_ostream &OS,
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<RefNode*>> &P) {
|
||||
switch (P.Obj.Addr->getKind()) {
|
||||
case NodeAttrs::Def:
|
||||
|
@ -177,7 +171,6 @@ raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<RefNode*>> &P) {
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<NodeList> &P) {
|
||||
unsigned N = P.Obj.size();
|
||||
for (auto I : P.Obj) {
|
||||
|
@ -188,7 +181,6 @@ raw_ostream &operator<< (raw_ostream &OS, const Print<NodeList> &P) {
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<NodeSet> &P) {
|
||||
unsigned N = P.Obj.size();
|
||||
for (auto I : P.Obj) {
|
||||
|
@ -223,16 +215,13 @@ namespace {
|
|||
|
||||
} // end anonymous namespace
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<PhiNode*>> &P) {
|
||||
OS << Print<NodeId>(P.Obj.Id, P.G) << ": phi ["
|
||||
<< PrintListV<RefNode*>(P.Obj.Addr->members(P.G), P.G) << ']';
|
||||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS,
|
||||
const Print<NodeAddr<StmtNode*>> &P) {
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<NodeAddr<StmtNode *>> &P) {
|
||||
const MachineInstr &MI = *P.Obj.Addr->getCode();
|
||||
unsigned Opc = MI.getOpcode();
|
||||
OS << Print<NodeId>(P.Obj.Id, P.G) << ": " << P.G.getTII().getName(Opc);
|
||||
|
@ -257,7 +246,6 @@ raw_ostream &operator<< (raw_ostream &OS,
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS,
|
||||
const Print<NodeAddr<InstrNode*>> &P) {
|
||||
switch (P.Obj.Addr->getKind()) {
|
||||
|
@ -274,7 +262,6 @@ raw_ostream &operator<< (raw_ostream &OS,
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS,
|
||||
const Print<NodeAddr<BlockNode*>> &P) {
|
||||
MachineBasicBlock *BB = P.Obj.Addr->getCode();
|
||||
|
@ -308,9 +295,7 @@ raw_ostream &operator<< (raw_ostream &OS,
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS,
|
||||
const Print<NodeAddr<FuncNode*>> &P) {
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<NodeAddr<FuncNode *>> &P) {
|
||||
OS << "DFG dump:[\n" << Print<NodeId>(P.Obj.Id, P.G) << ": Function: "
|
||||
<< P.Obj.Addr->getCode()->getName() << '\n';
|
||||
for (auto I : P.Obj.Addr->members(P.G))
|
||||
|
@ -319,7 +304,6 @@ raw_ostream &operator<< (raw_ostream &OS,
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterSet> &P) {
|
||||
OS << '{';
|
||||
for (auto I : P.Obj)
|
||||
|
@ -328,13 +312,11 @@ raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterSet> &P) {
|
|||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<RegisterAggr> &P) {
|
||||
P.Obj.print(OS);
|
||||
return OS;
|
||||
}
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS,
|
||||
const Print<DataFlowGraph::DefStack> &P) {
|
||||
for (auto I = P.Obj.top(), E = P.Obj.bottom(); I != E; ) {
|
||||
|
|
|
@ -924,10 +924,6 @@ namespace rdf {
|
|||
return MM;
|
||||
}
|
||||
|
||||
template <typename T> struct Print;
|
||||
template <typename T>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<T> &P);
|
||||
|
||||
template <typename T>
|
||||
struct Print {
|
||||
Print(const T &x, const DataFlowGraph &g) : Obj(x), G(g) {}
|
||||
|
@ -942,6 +938,29 @@ namespace rdf {
|
|||
: Print<NodeAddr<T>>(x, g) {}
|
||||
};
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterRef> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<NodeId> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<NodeAddr<DefNode *>> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<NodeAddr<UseNode *>> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS,
|
||||
const Print<NodeAddr<PhiUseNode *>> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<NodeAddr<RefNode *>> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<NodeList> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<NodeSet> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<NodeAddr<PhiNode *>> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS,
|
||||
const Print<NodeAddr<StmtNode *>> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS,
|
||||
const Print<NodeAddr<InstrNode *>> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS,
|
||||
const Print<NodeAddr<BlockNode *>> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS,
|
||||
const Print<NodeAddr<FuncNode *>> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterSet> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<RegisterAggr> &P);
|
||||
raw_ostream &operator<<(raw_ostream &OS,
|
||||
const Print<DataFlowGraph::DefStack> &P);
|
||||
|
||||
} // end namespace rdf
|
||||
|
||||
} // end namespace llvm
|
||||
|
|
|
@ -57,7 +57,6 @@ static cl::opt<unsigned> MaxRecNest("rdf-liveness-max-rec", cl::init(25),
|
|||
namespace llvm {
|
||||
namespace rdf {
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<Liveness::RefMap> &P) {
|
||||
OS << '{';
|
||||
for (auto &I : P.Obj) {
|
||||
|
|
|
@ -142,6 +142,8 @@ namespace rdf {
|
|||
unsigned Nest, unsigned MaxNest);
|
||||
};
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const Print<Liveness::RefMap> &P);
|
||||
|
||||
} // end namespace rdf
|
||||
|
||||
} // end namespace llvm
|
||||
|
|
Loading…
Reference in New Issue