mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
[Hexagon, TableGen] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).
llvm-svn: 290925
This commit is contained in:
parent
fd505c31d7
commit
c4c44537b4
@ -11,9 +11,15 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/TableGen/StringMatcher.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/TableGen/StringMatcher.h"
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
/// FindFirstNonCommonLetter - Find the first character in the keys of the
|
||||
@ -67,7 +73,7 @@ EmitStringMatcherForChar(const std::vector<const StringPair*> &Matches,
|
||||
}
|
||||
|
||||
// Bucket the matches by the character we are comparing.
|
||||
std::map<char, std::vector<const StringPair*> > MatchesByLetter;
|
||||
std::map<char, std::vector<const StringPair*>> MatchesByLetter;
|
||||
|
||||
for (unsigned i = 0, e = Matches.size(); i != e; ++i)
|
||||
MatchesByLetter[Matches[i]->first[CharNo]].push_back(Matches[i]);
|
||||
@ -91,7 +97,7 @@ EmitStringMatcherForChar(const std::vector<const StringPair*> &Matches,
|
||||
// FIXME: Need to escape general strings.
|
||||
OS << Indent << "if (memcmp(" << StrVariableName << ".data()+" << CharNo
|
||||
<< ", \"" << Matches[0]->first.substr(CharNo, NumChars) << "\", "
|
||||
<< NumChars << "))\n";
|
||||
<< NumChars << ") != 0)\n";
|
||||
OS << Indent << " break;\n";
|
||||
}
|
||||
|
||||
@ -103,7 +109,7 @@ EmitStringMatcherForChar(const std::vector<const StringPair*> &Matches,
|
||||
OS << Indent << "switch (" << StrVariableName << "[" << CharNo << "]) {\n";
|
||||
OS << Indent << "default: break;\n";
|
||||
|
||||
for (std::map<char, std::vector<const StringPair*> >::iterator LI =
|
||||
for (std::map<char, std::vector<const StringPair*>>::iterator LI =
|
||||
MatchesByLetter.begin(), E = MatchesByLetter.end(); LI != E; ++LI) {
|
||||
// TODO: escape hard stuff (like \n) if we ever care about it.
|
||||
OS << Indent << "case '" << LI->first << "':\t // "
|
||||
@ -118,7 +124,6 @@ EmitStringMatcherForChar(const std::vector<const StringPair*> &Matches,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
/// Emit - Top level entry point.
|
||||
///
|
||||
void StringMatcher::Emit(unsigned Indent) const {
|
||||
@ -126,7 +131,7 @@ void StringMatcher::Emit(unsigned Indent) const {
|
||||
if (Matches.empty()) return;
|
||||
|
||||
// First level categorization: group strings by length.
|
||||
std::map<unsigned, std::vector<const StringPair*> > MatchesByLength;
|
||||
std::map<unsigned, std::vector<const StringPair*>> MatchesByLength;
|
||||
|
||||
for (unsigned i = 0, e = Matches.size(); i != e; ++i)
|
||||
MatchesByLength[Matches[i].first.size()].push_back(&Matches[i]);
|
||||
@ -136,7 +141,7 @@ void StringMatcher::Emit(unsigned Indent) const {
|
||||
OS.indent(Indent*2+2) << "switch (" << StrVariableName << ".size()) {\n";
|
||||
OS.indent(Indent*2+2) << "default: break;\n";
|
||||
|
||||
for (std::map<unsigned, std::vector<const StringPair*> >::iterator LI =
|
||||
for (std::map<unsigned, std::vector<const StringPair*>>::iterator LI =
|
||||
MatchesByLength.begin(), E = MatchesByLength.end(); LI != E; ++LI) {
|
||||
OS.indent(Indent*2+2) << "case " << LI->first << ":\t // "
|
||||
<< LI->second.size()
|
||||
|
@ -53,28 +53,36 @@
|
||||
//
|
||||
// The code below is intended to be fully target-independent.
|
||||
|
||||
#include "BitTracker.h"
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
|
||||
#include "BitTracker.h"
|
||||
#include <iterator>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
typedef BitTracker BT;
|
||||
|
||||
namespace {
|
||||
|
||||
// Local trickery to pretty print a register (without the whole "%vreg"
|
||||
// business).
|
||||
struct printv {
|
||||
printv(unsigned r) : R(r) {}
|
||||
|
||||
unsigned R;
|
||||
};
|
||||
|
||||
raw_ostream &operator<< (raw_ostream &OS, const printv &PV) {
|
||||
if (PV.R)
|
||||
OS << 'v' << TargetRegisterInfo::virtReg2Index(PV.R);
|
||||
@ -82,9 +90,11 @@ namespace {
|
||||
OS << 's';
|
||||
return OS;
|
||||
}
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
namespace llvm {
|
||||
|
||||
raw_ostream &operator<<(raw_ostream &OS, const BT::BitValue &BV) {
|
||||
switch (BV.Type) {
|
||||
case BT::BitValue::Top:
|
||||
@ -167,14 +177,14 @@ namespace llvm {
|
||||
|
||||
return OS;
|
||||
}
|
||||
}
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
void BitTracker::print_cells(raw_ostream &OS) const {
|
||||
for (CellMapType::iterator I = Map.begin(), E = Map.end(); I != E; ++I)
|
||||
dbgs() << PrintReg(I->first, &ME.TRI) << " -> " << I->second << "\n";
|
||||
}
|
||||
|
||||
|
||||
BitTracker::BitTracker(const MachineEvaluator &E, MachineFunction &F)
|
||||
: Trace(false), ME(E), MF(F), MRI(F.getRegInfo()), Map(*new CellMapType) {}
|
||||
|
||||
@ -182,7 +192,6 @@ BitTracker::~BitTracker() {
|
||||
delete ⤅
|
||||
}
|
||||
|
||||
|
||||
// If we were allowed to update a cell for a part of a register, the meet
|
||||
// operation would need to be parametrized by the register number and the
|
||||
// exact part of the register, so that the computer BitRefs correspond to
|
||||
@ -201,7 +210,6 @@ bool BT::RegisterCell::meet(const RegisterCell &RC, unsigned SelfR) {
|
||||
return Changed;
|
||||
}
|
||||
|
||||
|
||||
// Insert the entire cell RC into the current cell at position given by M.
|
||||
BT::RegisterCell &BT::RegisterCell::insert(const BT::RegisterCell &RC,
|
||||
const BitMask &M) {
|
||||
@ -224,7 +232,6 @@ BT::RegisterCell &BT::RegisterCell::insert(const BT::RegisterCell &RC,
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::RegisterCell::extract(const BitMask &M) const {
|
||||
uint16_t B = M.first(), E = M.last(), W = width();
|
||||
assert(B < W && E < W);
|
||||
@ -243,7 +250,6 @@ BT::RegisterCell BT::RegisterCell::extract(const BitMask &M) const {
|
||||
return RC;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell &BT::RegisterCell::rol(uint16_t Sh) {
|
||||
// Rotate left (i.e. towards increasing bit indices).
|
||||
// Swap the two parts: [0..W-Sh-1] [W-Sh..W-1]
|
||||
@ -265,7 +271,6 @@ BT::RegisterCell &BT::RegisterCell::rol(uint16_t Sh) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell &BT::RegisterCell::fill(uint16_t B, uint16_t E,
|
||||
const BitValue &V) {
|
||||
assert(B <= E);
|
||||
@ -274,7 +279,6 @@ BT::RegisterCell &BT::RegisterCell::fill(uint16_t B, uint16_t E,
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell &BT::RegisterCell::cat(const RegisterCell &RC) {
|
||||
// Append the cell given as the argument to the "this" cell.
|
||||
// Bit 0 of RC becomes bit W of the result, where W is this->width().
|
||||
@ -285,7 +289,6 @@ BT::RegisterCell &BT::RegisterCell::cat(const RegisterCell &RC) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
uint16_t BT::RegisterCell::ct(bool B) const {
|
||||
uint16_t W = width();
|
||||
uint16_t C = 0;
|
||||
@ -295,7 +298,6 @@ uint16_t BT::RegisterCell::ct(bool B) const {
|
||||
return C;
|
||||
}
|
||||
|
||||
|
||||
uint16_t BT::RegisterCell::cl(bool B) const {
|
||||
uint16_t W = width();
|
||||
uint16_t C = 0;
|
||||
@ -305,7 +307,6 @@ uint16_t BT::RegisterCell::cl(bool B) const {
|
||||
return C;
|
||||
}
|
||||
|
||||
|
||||
bool BT::RegisterCell::operator== (const RegisterCell &RC) const {
|
||||
uint16_t W = Bits.size();
|
||||
if (RC.Bits.size() != W)
|
||||
@ -316,7 +317,6 @@ bool BT::RegisterCell::operator== (const RegisterCell &RC) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
uint16_t BT::MachineEvaluator::getRegBitWidth(const RegisterRef &RR) const {
|
||||
// The general problem is with finding a register class that corresponds
|
||||
// to a given reference reg:sub. There can be several such classes, and
|
||||
@ -342,7 +342,6 @@ uint16_t BT::MachineEvaluator::getRegBitWidth(const RegisterRef &RR) const {
|
||||
return BW;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::getCell(const RegisterRef &RR,
|
||||
const CellMapType &M) const {
|
||||
uint16_t BW = getRegBitWidth(RR);
|
||||
@ -370,7 +369,6 @@ BT::RegisterCell BT::MachineEvaluator::getCell(const RegisterRef &RR,
|
||||
return RegisterCell::top(BW);
|
||||
}
|
||||
|
||||
|
||||
void BT::MachineEvaluator::putCell(const RegisterRef &RR, RegisterCell RC,
|
||||
CellMapType &M) const {
|
||||
// While updating the cell map can be done in a meaningful way for
|
||||
@ -388,7 +386,6 @@ void BT::MachineEvaluator::putCell(const RegisterRef &RR, RegisterCell RC,
|
||||
M[RR.Reg] = RC;
|
||||
}
|
||||
|
||||
|
||||
// Check if the cell represents a compile-time integer value.
|
||||
bool BT::MachineEvaluator::isInt(const RegisterCell &A) const {
|
||||
uint16_t W = A.width();
|
||||
@ -398,7 +395,6 @@ bool BT::MachineEvaluator::isInt(const RegisterCell &A) const {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Convert a cell to the integer value. The result must fit in uint64_t.
|
||||
uint64_t BT::MachineEvaluator::toInt(const RegisterCell &A) const {
|
||||
assert(isInt(A));
|
||||
@ -411,7 +407,6 @@ uint64_t BT::MachineEvaluator::toInt(const RegisterCell &A) const {
|
||||
return Val;
|
||||
}
|
||||
|
||||
|
||||
// Evaluator helper functions. These implement some common operation on
|
||||
// register cells that can be used to implement target-specific instructions
|
||||
// in a target-specific evaluator.
|
||||
@ -426,7 +421,6 @@ BT::RegisterCell BT::MachineEvaluator::eIMM(int64_t V, uint16_t W) const {
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eIMM(const ConstantInt *CI) const {
|
||||
const APInt &A = CI->getValue();
|
||||
uint16_t BW = A.getBitWidth();
|
||||
@ -437,7 +431,6 @@ BT::RegisterCell BT::MachineEvaluator::eIMM(const ConstantInt *CI) const {
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eADD(const RegisterCell &A1,
|
||||
const RegisterCell &A2) const {
|
||||
uint16_t W = A1.width();
|
||||
@ -471,7 +464,6 @@ BT::RegisterCell BT::MachineEvaluator::eADD(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eSUB(const RegisterCell &A1,
|
||||
const RegisterCell &A2) const {
|
||||
uint16_t W = A1.width();
|
||||
@ -505,29 +497,26 @@ BT::RegisterCell BT::MachineEvaluator::eSUB(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eMLS(const RegisterCell &A1,
|
||||
const RegisterCell &A2) const {
|
||||
uint16_t W = A1.width() + A2.width();
|
||||
uint16_t Z = A1.ct(0) + A2.ct(0);
|
||||
uint16_t Z = A1.ct(false) + A2.ct(false);
|
||||
RegisterCell Res(W);
|
||||
Res.fill(0, Z, BitValue::Zero);
|
||||
Res.fill(Z, W, BitValue::self());
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eMLU(const RegisterCell &A1,
|
||||
const RegisterCell &A2) const {
|
||||
uint16_t W = A1.width() + A2.width();
|
||||
uint16_t Z = A1.ct(0) + A2.ct(0);
|
||||
uint16_t Z = A1.ct(false) + A2.ct(false);
|
||||
RegisterCell Res(W);
|
||||
Res.fill(0, Z, BitValue::Zero);
|
||||
Res.fill(Z, W, BitValue::self());
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eASL(const RegisterCell &A1,
|
||||
uint16_t Sh) const {
|
||||
assert(Sh <= A1.width());
|
||||
@ -537,7 +526,6 @@ BT::RegisterCell BT::MachineEvaluator::eASL(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eLSR(const RegisterCell &A1,
|
||||
uint16_t Sh) const {
|
||||
uint16_t W = A1.width();
|
||||
@ -548,7 +536,6 @@ BT::RegisterCell BT::MachineEvaluator::eLSR(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eASR(const RegisterCell &A1,
|
||||
uint16_t Sh) const {
|
||||
uint16_t W = A1.width();
|
||||
@ -560,7 +547,6 @@ BT::RegisterCell BT::MachineEvaluator::eASR(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eAND(const RegisterCell &A1,
|
||||
const RegisterCell &A2) const {
|
||||
uint16_t W = A1.width();
|
||||
@ -583,7 +569,6 @@ BT::RegisterCell BT::MachineEvaluator::eAND(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eORL(const RegisterCell &A1,
|
||||
const RegisterCell &A2) const {
|
||||
uint16_t W = A1.width();
|
||||
@ -606,7 +591,6 @@ BT::RegisterCell BT::MachineEvaluator::eORL(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eXOR(const RegisterCell &A1,
|
||||
const RegisterCell &A2) const {
|
||||
uint16_t W = A1.width();
|
||||
@ -627,7 +611,6 @@ BT::RegisterCell BT::MachineEvaluator::eXOR(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eNOT(const RegisterCell &A1) const {
|
||||
uint16_t W = A1.width();
|
||||
RegisterCell Res(W);
|
||||
@ -643,7 +626,6 @@ BT::RegisterCell BT::MachineEvaluator::eNOT(const RegisterCell &A1) const {
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eSET(const RegisterCell &A1,
|
||||
uint16_t BitN) const {
|
||||
assert(BitN < A1.width());
|
||||
@ -652,7 +634,6 @@ BT::RegisterCell BT::MachineEvaluator::eSET(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eCLR(const RegisterCell &A1,
|
||||
uint16_t BitN) const {
|
||||
assert(BitN < A1.width());
|
||||
@ -661,7 +642,6 @@ BT::RegisterCell BT::MachineEvaluator::eCLR(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eCLB(const RegisterCell &A1, bool B,
|
||||
uint16_t W) const {
|
||||
uint16_t C = A1.cl(B), AW = A1.width();
|
||||
@ -672,7 +652,6 @@ BT::RegisterCell BT::MachineEvaluator::eCLB(const RegisterCell &A1, bool B,
|
||||
return RegisterCell::self(0, W);
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eCTB(const RegisterCell &A1, bool B,
|
||||
uint16_t W) const {
|
||||
uint16_t C = A1.ct(B), AW = A1.width();
|
||||
@ -683,7 +662,6 @@ BT::RegisterCell BT::MachineEvaluator::eCTB(const RegisterCell &A1, bool B,
|
||||
return RegisterCell::self(0, W);
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eSXT(const RegisterCell &A1,
|
||||
uint16_t FromN) const {
|
||||
uint16_t W = A1.width();
|
||||
@ -695,7 +673,6 @@ BT::RegisterCell BT::MachineEvaluator::eSXT(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eZXT(const RegisterCell &A1,
|
||||
uint16_t FromN) const {
|
||||
uint16_t W = A1.width();
|
||||
@ -705,7 +682,6 @@ BT::RegisterCell BT::MachineEvaluator::eZXT(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eXTR(const RegisterCell &A1,
|
||||
uint16_t B, uint16_t E) const {
|
||||
uint16_t W = A1.width();
|
||||
@ -718,7 +694,6 @@ BT::RegisterCell BT::MachineEvaluator::eXTR(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::MachineEvaluator::eINS(const RegisterCell &A1,
|
||||
const RegisterCell &A2, uint16_t AtN) const {
|
||||
uint16_t W1 = A1.width(), W2 = A2.width();
|
||||
@ -731,7 +706,6 @@ BT::RegisterCell BT::MachineEvaluator::eINS(const RegisterCell &A1,
|
||||
return Res;
|
||||
}
|
||||
|
||||
|
||||
BT::BitMask BT::MachineEvaluator::mask(unsigned Reg, unsigned Sub) const {
|
||||
assert(Sub == 0 && "Generic BitTracker::mask called for Sub != 0");
|
||||
uint16_t W = getRegBitWidth(Reg);
|
||||
@ -785,7 +759,6 @@ bool BT::MachineEvaluator::evaluate(const MachineInstr &MI,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Main W-Z implementation.
|
||||
|
||||
void BT::visitPHI(const MachineInstr &PI) {
|
||||
@ -977,7 +950,6 @@ void BT::visitBranchesFrom(const MachineInstr &BI) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void BT::visitUsesOf(unsigned Reg) {
|
||||
if (Trace)
|
||||
dbgs() << "visiting uses of " << PrintReg(Reg, &ME.TRI) << "\n";
|
||||
@ -997,17 +969,14 @@ void BT::visitUsesOf(unsigned Reg) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BT::RegisterCell BT::get(RegisterRef RR) const {
|
||||
return ME.getCell(RR, Map);
|
||||
}
|
||||
|
||||
|
||||
void BT::put(RegisterRef RR, const RegisterCell &RC) {
|
||||
ME.putCell(RR, RC, Map);
|
||||
}
|
||||
|
||||
|
||||
// Replace all references to bits from OldRR with the corresponding bits
|
||||
// in NewRR.
|
||||
void BT::subst(RegisterRef OldRR, RegisterRef NewRR) {
|
||||
@ -1033,7 +1002,6 @@ void BT::subst(RegisterRef OldRR, RegisterRef NewRR) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Check if the block has been "executed" during propagation. (If not, the
|
||||
// block is dead, but it may still appear to be reachable.)
|
||||
bool BT::reached(const MachineBasicBlock *B) const {
|
||||
@ -1047,7 +1015,6 @@ bool BT::reached(const MachineBasicBlock *B) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Visit an individual instruction. This could be a newly added instruction,
|
||||
// or one that has been modified by an optimization.
|
||||
void BT::visit(const MachineInstr &MI) {
|
||||
@ -1061,14 +1028,12 @@ void BT::visit(const MachineInstr &MI) {
|
||||
FlowQ.pop();
|
||||
}
|
||||
|
||||
|
||||
void BT::reset() {
|
||||
EdgeExec.clear();
|
||||
InstrExec.clear();
|
||||
Map.clear();
|
||||
}
|
||||
|
||||
|
||||
void BT::run() {
|
||||
reset();
|
||||
assert(FlowQ.empty());
|
||||
@ -1141,4 +1106,3 @@ void BT::run() {
|
||||
if (Trace)
|
||||
print_cells(dbgs() << "Cells after propagation:\n");
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- BitTracker.h -----------------------------------------------------===//
|
||||
//===--- BitTracker.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -7,24 +7,27 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef BITTRACKER_H
|
||||
#define BITTRACKER_H
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_BITTRACKER_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_BITTRACKER_H
|
||||
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <queue>
|
||||
#include <set>
|
||||
#include <utility>
|
||||
|
||||
namespace llvm {
|
||||
class ConstantInt;
|
||||
class MachineRegisterInfo;
|
||||
class MachineBasicBlock;
|
||||
class MachineInstr;
|
||||
class MachineOperand;
|
||||
class raw_ostream;
|
||||
|
||||
class ConstantInt;
|
||||
class MachineRegisterInfo;
|
||||
class MachineBasicBlock;
|
||||
class MachineInstr;
|
||||
class raw_ostream;
|
||||
|
||||
struct BitTracker {
|
||||
struct BitRef;
|
||||
@ -76,19 +79,19 @@ private:
|
||||
CellMapType ⤅
|
||||
};
|
||||
|
||||
|
||||
// Abstraction of a reference to bit at position Pos from a register Reg.
|
||||
struct BitTracker::BitRef {
|
||||
BitRef(unsigned R = 0, uint16_t P = 0) : Reg(R), Pos(P) {}
|
||||
|
||||
bool operator== (const BitRef &BR) const {
|
||||
// If Reg is 0, disregard Pos.
|
||||
return Reg == BR.Reg && (Reg == 0 || Pos == BR.Pos);
|
||||
}
|
||||
|
||||
unsigned Reg;
|
||||
uint16_t Pos;
|
||||
};
|
||||
|
||||
|
||||
// Abstraction of a register reference in MachineOperand. It contains the
|
||||
// register number and the subregister index.
|
||||
struct BitTracker::RegisterRef {
|
||||
@ -96,10 +99,10 @@ struct BitTracker::RegisterRef {
|
||||
: Reg(R), Sub(S) {}
|
||||
RegisterRef(const MachineOperand &MO)
|
||||
: Reg(MO.getReg()), Sub(MO.getSubReg()) {}
|
||||
|
||||
unsigned Reg, Sub;
|
||||
};
|
||||
|
||||
|
||||
// Value that a single bit can take. This is outside of the context of
|
||||
// any register, it is more of an abstraction of the two-element set of
|
||||
// possible bit values. One extension here is the "Ref" type, which
|
||||
@ -158,6 +161,7 @@ struct BitTracker::BitValue {
|
||||
bool operator!= (const BitValue &V) const {
|
||||
return !operator==(V);
|
||||
}
|
||||
|
||||
bool is(unsigned T) const {
|
||||
assert(T == 0 || T == 1);
|
||||
return T == 0 ? Type == Zero
|
||||
@ -209,6 +213,7 @@ struct BitTracker::BitValue {
|
||||
bool num() const {
|
||||
return Type == Zero || Type == One;
|
||||
}
|
||||
|
||||
operator bool() const {
|
||||
assert(Type == Zero || Type == One);
|
||||
return Type == One;
|
||||
@ -217,7 +222,6 @@ struct BitTracker::BitValue {
|
||||
friend raw_ostream &operator<<(raw_ostream &OS, const BitValue &BV);
|
||||
};
|
||||
|
||||
|
||||
// This operation must be idempotent, i.e. ref(ref(V)) == ref(V).
|
||||
inline BitTracker::BitValue
|
||||
BitTracker::BitValue::ref(const BitValue &V) {
|
||||
@ -228,25 +232,25 @@ BitTracker::BitValue::ref(const BitValue &V) {
|
||||
return self();
|
||||
}
|
||||
|
||||
|
||||
inline BitTracker::BitValue
|
||||
BitTracker::BitValue::self(const BitRef &Self) {
|
||||
return BitValue(Self.Reg, Self.Pos);
|
||||
}
|
||||
|
||||
|
||||
// A sequence of bits starting from index B up to and including index E.
|
||||
// If E < B, the mask represents two sections: [0..E] and [B..W) where
|
||||
// W is the width of the register.
|
||||
struct BitTracker::BitMask {
|
||||
BitMask() : B(0), E(0) {}
|
||||
BitMask() = default;
|
||||
BitMask(uint16_t b, uint16_t e) : B(b), E(e) {}
|
||||
|
||||
uint16_t first() const { return B; }
|
||||
uint16_t last() const { return E; }
|
||||
private:
|
||||
uint16_t B, E;
|
||||
};
|
||||
|
||||
private:
|
||||
uint16_t B = 0;
|
||||
uint16_t E = 0;
|
||||
};
|
||||
|
||||
// Representation of a register: a list of BitValues.
|
||||
struct BitTracker::RegisterCell {
|
||||
@ -255,6 +259,7 @@ struct BitTracker::RegisterCell {
|
||||
uint16_t width() const {
|
||||
return Bits.size();
|
||||
}
|
||||
|
||||
const BitValue &operator[](uint16_t BitN) const {
|
||||
assert(BitN < Bits.size());
|
||||
return Bits[BitN];
|
||||
@ -297,12 +302,10 @@ private:
|
||||
friend raw_ostream &operator<<(raw_ostream &OS, const RegisterCell &RC);
|
||||
};
|
||||
|
||||
|
||||
inline bool BitTracker::has(unsigned Reg) const {
|
||||
return Map.find(Reg) != Map.end();
|
||||
}
|
||||
|
||||
|
||||
inline const BitTracker::RegisterCell&
|
||||
BitTracker::lookup(unsigned Reg) const {
|
||||
CellMapType::const_iterator F = Map.find(Reg);
|
||||
@ -310,7 +313,6 @@ BitTracker::lookup(unsigned Reg) const {
|
||||
return F->second;
|
||||
}
|
||||
|
||||
|
||||
inline BitTracker::RegisterCell
|
||||
BitTracker::RegisterCell::self(unsigned Reg, uint16_t Width) {
|
||||
RegisterCell RC(Width);
|
||||
@ -319,7 +321,6 @@ BitTracker::RegisterCell::self(unsigned Reg, uint16_t Width) {
|
||||
return RC;
|
||||
}
|
||||
|
||||
|
||||
inline BitTracker::RegisterCell
|
||||
BitTracker::RegisterCell::top(uint16_t Width) {
|
||||
RegisterCell RC(Width);
|
||||
@ -328,7 +329,6 @@ BitTracker::RegisterCell::top(uint16_t Width) {
|
||||
return RC;
|
||||
}
|
||||
|
||||
|
||||
inline BitTracker::RegisterCell
|
||||
BitTracker::RegisterCell::ref(const RegisterCell &C) {
|
||||
uint16_t W = C.width();
|
||||
@ -345,12 +345,13 @@ BitTracker::RegisterCell::ref(const RegisterCell &C) {
|
||||
struct BitTracker::MachineEvaluator {
|
||||
MachineEvaluator(const TargetRegisterInfo &T, MachineRegisterInfo &M)
|
||||
: TRI(T), MRI(M) {}
|
||||
virtual ~MachineEvaluator() {}
|
||||
virtual ~MachineEvaluator() = default;
|
||||
|
||||
uint16_t getRegBitWidth(const RegisterRef &RR) const;
|
||||
|
||||
RegisterCell getCell(const RegisterRef &RR, const CellMapType &M) const;
|
||||
void putCell(const RegisterRef &RR, RegisterCell RC, CellMapType &M) const;
|
||||
|
||||
// A result of any operation should use refs to the source cells, not
|
||||
// the cells directly. This function is a convenience wrapper to quickly
|
||||
// generate a ref for a cell corresponding to a register reference.
|
||||
@ -435,4 +436,4 @@ struct BitTracker::MachineEvaluator {
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_BITTRACKER_H
|
||||
|
@ -7,16 +7,30 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonBitTracker.h"
|
||||
#include "HexagonInstrInfo.h"
|
||||
#include "HexagonRegisterInfo.h"
|
||||
#include "HexagonTargetMachine.h"
|
||||
#include "HexagonBitTracker.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/IR/Argument.h"
|
||||
#include "llvm/IR/Attributes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <cstdlib>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -76,11 +90,11 @@ HexagonEvaluator::HexagonEvaluator(const HexagonRegisterInfo &tri,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
BT::BitMask HexagonEvaluator::mask(unsigned Reg, unsigned Sub) const {
|
||||
using namespace Hexagon;
|
||||
|
||||
if (Sub == 0)
|
||||
return MachineEvaluator::mask(Reg, 0);
|
||||
using namespace Hexagon;
|
||||
const TargetRegisterClass *RC = MRI.getRegClass(Reg);
|
||||
unsigned ID = RC->getID();
|
||||
uint16_t RW = getRegBitWidth(RegisterRef(Reg, Sub));
|
||||
@ -102,6 +116,7 @@ BT::BitMask HexagonEvaluator::mask(unsigned Reg, unsigned Sub) const {
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
class RegisterRefs {
|
||||
std::vector<BT::RegisterRef> Vector;
|
||||
|
||||
@ -117,17 +132,21 @@ public:
|
||||
}
|
||||
|
||||
size_t size() const { return Vector.size(); }
|
||||
|
||||
const BT::RegisterRef &operator[](unsigned n) const {
|
||||
// The main purpose of this operator is to assert with bad argument.
|
||||
assert(n < Vector.size());
|
||||
return Vector[n];
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
bool HexagonEvaluator::evaluate(const MachineInstr &MI,
|
||||
const CellMapType &Inputs,
|
||||
CellMapType &Outputs) const {
|
||||
using namespace Hexagon;
|
||||
|
||||
unsigned NumDefs = 0;
|
||||
|
||||
// Sanity verification: there should not be any defs with subregisters.
|
||||
@ -142,7 +161,6 @@ bool HexagonEvaluator::evaluate(const MachineInstr &MI,
|
||||
if (NumDefs == 0)
|
||||
return false;
|
||||
|
||||
using namespace Hexagon;
|
||||
unsigned Opc = MI.getOpcode();
|
||||
|
||||
if (MI.mayLoad()) {
|
||||
@ -779,10 +797,10 @@ bool HexagonEvaluator::evaluate(const MachineInstr &MI,
|
||||
case S2_cl0:
|
||||
case S2_cl0p:
|
||||
// Always produce a 32-bit result.
|
||||
return rr0(eCLB(rc(1), 0/*bit*/, 32), Outputs);
|
||||
return rr0(eCLB(rc(1), false/*bit*/, 32), Outputs);
|
||||
case S2_cl1:
|
||||
case S2_cl1p:
|
||||
return rr0(eCLB(rc(1), 1/*bit*/, 32), Outputs);
|
||||
return rr0(eCLB(rc(1), true/*bit*/, 32), Outputs);
|
||||
case S2_clb:
|
||||
case S2_clbp: {
|
||||
uint16_t W1 = getRegBitWidth(Reg[1]);
|
||||
@ -794,10 +812,10 @@ bool HexagonEvaluator::evaluate(const MachineInstr &MI,
|
||||
}
|
||||
case S2_ct0:
|
||||
case S2_ct0p:
|
||||
return rr0(eCTB(rc(1), 0/*bit*/, 32), Outputs);
|
||||
return rr0(eCTB(rc(1), false/*bit*/, 32), Outputs);
|
||||
case S2_ct1:
|
||||
case S2_ct1p:
|
||||
return rr0(eCTB(rc(1), 1/*bit*/, 32), Outputs);
|
||||
return rr0(eCTB(rc(1), true/*bit*/, 32), Outputs);
|
||||
case S5_popcountp:
|
||||
// TODO
|
||||
break;
|
||||
@ -953,6 +971,8 @@ bool HexagonEvaluator::evaluate(const MachineInstr &BI,
|
||||
bool HexagonEvaluator::evaluateLoad(const MachineInstr &MI,
|
||||
const CellMapType &Inputs,
|
||||
CellMapType &Outputs) const {
|
||||
using namespace Hexagon;
|
||||
|
||||
if (TII.isPredicated(MI))
|
||||
return false;
|
||||
assert(MI.mayLoad() && "A load that mayn't?");
|
||||
@ -960,7 +980,6 @@ bool HexagonEvaluator::evaluateLoad(const MachineInstr &MI,
|
||||
|
||||
uint16_t BitNum;
|
||||
bool SignEx;
|
||||
using namespace Hexagon;
|
||||
|
||||
switch (Opc) {
|
||||
default:
|
||||
@ -1141,9 +1160,9 @@ bool HexagonEvaluator::evaluateFormalCopy(const MachineInstr &MI,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
unsigned HexagonEvaluator::getNextPhysReg(unsigned PReg, unsigned Width) const {
|
||||
using namespace Hexagon;
|
||||
|
||||
bool Is64 = DoubleRegsRegClass.contains(PReg);
|
||||
assert(PReg == 0 || Is64 || IntRegsRegClass.contains(PReg));
|
||||
|
||||
@ -1180,7 +1199,6 @@ unsigned HexagonEvaluator::getNextPhysReg(unsigned PReg, unsigned Width) const {
|
||||
return (Idx64+1 < Num64) ? Phys64[Idx64+1] : 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned HexagonEvaluator::getVirtRegFor(unsigned PReg) const {
|
||||
typedef MachineRegisterInfo::livein_iterator iterator;
|
||||
for (iterator I = MRI.livein_begin(), E = MRI.livein_end(); I != E; ++I) {
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- HexagonBitTracker.h ----------------------------------------------===//
|
||||
//===--- HexagonBitTracker.h ------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -7,15 +7,17 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef HEXAGONBITTRACKER_H
|
||||
#define HEXAGONBITTRACKER_H
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONBITTRACKER_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_HEXAGONBITTRACKER_H
|
||||
|
||||
#include "BitTracker.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include <cstdint>
|
||||
|
||||
namespace llvm {
|
||||
class HexagonInstrInfo;
|
||||
class HexagonRegisterInfo;
|
||||
|
||||
class HexagonInstrInfo;
|
||||
class HexagonRegisterInfo;
|
||||
|
||||
struct HexagonEvaluator : public BitTracker::MachineEvaluator {
|
||||
typedef BitTracker::CellMapType CellMapType;
|
||||
@ -49,10 +51,12 @@ private:
|
||||
// Type of formal parameter extension.
|
||||
struct ExtType {
|
||||
enum { SExt, ZExt };
|
||||
char Type;
|
||||
uint16_t Width;
|
||||
ExtType() : Type(0), Width(0) {}
|
||||
|
||||
ExtType() = default;
|
||||
ExtType(char t, uint16_t w) : Type(t), Width(w) {}
|
||||
|
||||
char Type = 0;
|
||||
uint16_t Width = 0;
|
||||
};
|
||||
// Map VR -> extension type.
|
||||
typedef DenseMap<unsigned, ExtType> RegExtMap;
|
||||
@ -61,4 +65,4 @@ private:
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONBITTRACKER_H
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -16,9 +16,14 @@
|
||||
|
||||
#include "HexagonRegisterInfo.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
|
||||
#include "llvm/Target/TargetFrameLowering.h"
|
||||
#include "llvm/CodeGen/MachineValueType.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
||||
#define GET_INSTRINFO_HEADER
|
||||
#include "HexagonGenInstrInfo.inc"
|
||||
@ -29,9 +34,10 @@ struct EVT;
|
||||
class HexagonSubtarget;
|
||||
|
||||
class HexagonInstrInfo : public HexagonGenInstrInfo {
|
||||
virtual void anchor();
|
||||
const HexagonRegisterInfo RI;
|
||||
|
||||
virtual void anchor();
|
||||
|
||||
public:
|
||||
explicit HexagonInstrInfo(HexagonSubtarget &ST);
|
||||
|
||||
@ -260,7 +266,7 @@ public:
|
||||
/// PredCost.
|
||||
unsigned getInstrLatency(const InstrItineraryData *ItinData,
|
||||
const MachineInstr &MI,
|
||||
unsigned *PredCost = 0) const override;
|
||||
unsigned *PredCost = nullptr) const override;
|
||||
|
||||
/// Create machine specific model for scheduling.
|
||||
DFAPacketizer *
|
||||
@ -378,7 +384,6 @@ public:
|
||||
bool PredOpcodeHasJMP_c(unsigned Opcode) const;
|
||||
bool predOpcodeHasNot(ArrayRef<MachineOperand> Cond) const;
|
||||
|
||||
|
||||
short getAbsoluteForm(const MachineInstr &MI) const;
|
||||
unsigned getAddrMode(const MachineInstr &MI) const;
|
||||
unsigned getBaseAndOffset(const MachineInstr &MI, int &Offset,
|
||||
@ -421,13 +426,11 @@ public:
|
||||
unsigned getUnits(const MachineInstr &MI) const;
|
||||
unsigned getValidSubTargets(const unsigned Opcode) const;
|
||||
|
||||
|
||||
/// getInstrTimingClassLatency - Compute the instruction latency of a given
|
||||
/// instruction using Timing Class information, if available.
|
||||
unsigned nonDbgBBSize(const MachineBasicBlock *BB) const;
|
||||
unsigned nonDbgBundleSize(MachineBasicBlock::const_iterator BundleHead) const;
|
||||
|
||||
|
||||
void immediateExtend(MachineInstr &MI) const;
|
||||
bool invertAndChangeJumpTarget(MachineInstr &MI,
|
||||
MachineBasicBlock* NewTarget) const;
|
||||
@ -438,6 +441,6 @@ public:
|
||||
short xformRegToImmOffset(const MachineInstr &MI) const;
|
||||
};
|
||||
|
||||
}
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONINSTRINFO_H
|
||||
|
@ -15,33 +15,31 @@
|
||||
|
||||
namespace llvm {
|
||||
|
||||
namespace Hexagon {
|
||||
namespace Hexagon {
|
||||
|
||||
const unsigned int StartPacket = 0x1;
|
||||
const unsigned int EndPacket = 0x2;
|
||||
}
|
||||
|
||||
} // end namespace Hexagon
|
||||
|
||||
/// Hexagon target-specific information for each MachineFunction.
|
||||
class HexagonMachineFunctionInfo : public MachineFunctionInfo {
|
||||
// SRetReturnReg - Some subtargets require that sret lowering includes
|
||||
// returning the value of the returned struct in a register. This field
|
||||
// holds the virtual register into which the sret argument is passed.
|
||||
unsigned SRetReturnReg;
|
||||
unsigned StackAlignBaseVReg; // Aligned-stack base register (virtual)
|
||||
unsigned StackAlignBasePhysReg; // (physical)
|
||||
unsigned SRetReturnReg = 0;
|
||||
unsigned StackAlignBaseVReg = 0; // Aligned-stack base register (virtual)
|
||||
unsigned StackAlignBasePhysReg = 0; // (physical)
|
||||
int VarArgsFrameIndex;
|
||||
bool HasClobberLR;
|
||||
bool HasEHReturn;
|
||||
bool HasClobberLR = false;
|
||||
bool HasEHReturn = false;
|
||||
std::map<const MachineInstr*, unsigned> PacketInfo;
|
||||
virtual void anchor();
|
||||
|
||||
public:
|
||||
HexagonMachineFunctionInfo() : SRetReturnReg(0), StackAlignBaseVReg(0),
|
||||
StackAlignBasePhysReg(0), HasClobberLR(0), HasEHReturn(false) {}
|
||||
HexagonMachineFunctionInfo() = default;
|
||||
|
||||
HexagonMachineFunctionInfo(MachineFunction &MF) : SRetReturnReg(0),
|
||||
StackAlignBaseVReg(0), StackAlignBasePhysReg(0), HasClobberLR(0),
|
||||
HasEHReturn(false) {}
|
||||
HexagonMachineFunctionInfo(MachineFunction &MF) {}
|
||||
|
||||
unsigned getSRetReturnReg() const { return SRetReturnReg; }
|
||||
void setSRetReturnReg(unsigned Reg) { SRetReturnReg = Reg; }
|
||||
@ -75,6 +73,7 @@ public:
|
||||
void setStackAlignBasePhysReg(unsigned R) { StackAlignBasePhysReg = R; }
|
||||
unsigned getStackAlignBasePhysReg() const { return StackAlignBasePhysReg; }
|
||||
};
|
||||
} // End llvm namespace
|
||||
|
||||
#endif
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINEFUNCTIONINFO_H
|
||||
|
@ -10,17 +10,27 @@
|
||||
// This file contains the declarations of the HexagonTargetAsmInfo properties.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "hexagon-sdata"
|
||||
|
||||
#include "HexagonTargetMachine.h"
|
||||
#include "HexagonTargetObjectFile.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/DerivedTypes.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/IR/GlobalObject.h"
|
||||
#include "llvm/IR/GlobalValue.h"
|
||||
#include "llvm/IR/GlobalVariable.h"
|
||||
#include "llvm/IR/Type.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/SectionKind.h"
|
||||
#include "llvm/Support/Casting.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ELF.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
@ -44,13 +54,21 @@ static cl::opt<bool> TraceGVPlacement("trace-gv-placement",
|
||||
// (e.g. -debug and -debug-only=globallayout)
|
||||
#define TRACE_TO(s, X) s << X
|
||||
#ifdef NDEBUG
|
||||
#define TRACE(X) do { if (TraceGVPlacement) { TRACE_TO(errs(), X); } } while (0)
|
||||
#define TRACE(X) \
|
||||
do { \
|
||||
if (TraceGVPlacement) { \
|
||||
TRACE_TO(errs(), X); \
|
||||
} \
|
||||
} while (false)
|
||||
#else
|
||||
#define TRACE(X) \
|
||||
do { \
|
||||
if (TraceGVPlacement) { TRACE_TO(errs(), X); } \
|
||||
else { DEBUG( TRACE_TO(dbgs(), X) ); } \
|
||||
} while (0)
|
||||
#define TRACE(X) \
|
||||
do { \
|
||||
if (TraceGVPlacement) { \
|
||||
TRACE_TO(errs(), X); \
|
||||
} else { \
|
||||
DEBUG(TRACE_TO(dbgs(), X)); \
|
||||
} \
|
||||
} while (false)
|
||||
#endif
|
||||
|
||||
// Returns true if the section name is such that the symbol will be put
|
||||
@ -69,7 +87,6 @@ static bool isSmallDataSection(StringRef Sec) {
|
||||
Sec.find(".scommon.") != StringRef::npos;
|
||||
}
|
||||
|
||||
|
||||
static const char *getSectionSuffixForSize(unsigned Size) {
|
||||
switch (Size) {
|
||||
default:
|
||||
@ -163,7 +180,6 @@ MCSection *HexagonTargetObjectFile::getExplicitSectionGlobal(
|
||||
return TargetLoweringObjectFileELF::getExplicitSectionGlobal(GO, Kind, TM);
|
||||
}
|
||||
|
||||
|
||||
/// Return true if this global value should be placed into small data/bss
|
||||
/// section.
|
||||
bool HexagonTargetObjectFile::isGlobalInSmallSection(const GlobalObject *GO,
|
||||
@ -232,17 +248,14 @@ bool HexagonTargetObjectFile::isGlobalInSmallSection(const GlobalObject *GO,
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool HexagonTargetObjectFile::isSmallDataEnabled() const {
|
||||
return SmallDataThreshold > 0;
|
||||
}
|
||||
|
||||
|
||||
unsigned HexagonTargetObjectFile::getSmallDataSize() const {
|
||||
return SmallDataThreshold;
|
||||
}
|
||||
|
||||
|
||||
/// Descends any type down to "elementary" components,
|
||||
/// discovering the smallest addressable one.
|
||||
/// If zero is returned, declaration will not be modified.
|
||||
|
@ -1,5 +1,4 @@
|
||||
|
||||
//=== HexagonMCCompound.cpp - Hexagon Compound checker -------===//
|
||||
//=== HexagonMCCompound.cpp - Hexagon Compound checker -------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -11,18 +10,17 @@
|
||||
// This file is looks at a packet and tries to form compound insns
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Hexagon.h"
|
||||
#include "MCTargetDesc/HexagonBaseInfo.h"
|
||||
#include "MCTargetDesc/HexagonMCShuffler.h"
|
||||
#include "llvm/ADT/StringExtras.h"
|
||||
#include "llvm/MC/MCAssembler.h"
|
||||
#include "MCTargetDesc/HexagonMCInstrInfo.h"
|
||||
#include "llvm/MC/MCContext.h"
|
||||
#include "llvm/MC/MCInst.h"
|
||||
#include "llvm/MC/MCSectionELF.h"
|
||||
#include "llvm/MC/MCStreamer.h"
|
||||
#include "llvm/MC/MCSymbol.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace Hexagon;
|
||||
@ -79,8 +77,7 @@ static const unsigned cmpgtn1BitOpcode[8] = {
|
||||
};
|
||||
|
||||
// enum HexagonII::CompoundGroup
|
||||
namespace {
|
||||
unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
|
||||
static unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
|
||||
unsigned DstReg, SrcReg, Src1Reg, Src2Reg;
|
||||
|
||||
switch (MI.getOpcode()) {
|
||||
@ -173,11 +170,9 @@ unsigned getCompoundCandidateGroup(MCInst const &MI, bool IsExtended) {
|
||||
|
||||
return HexagonII::HCG_None;
|
||||
}
|
||||
}
|
||||
|
||||
/// getCompoundOp - Return the index from 0-7 into the above opcode lists.
|
||||
namespace {
|
||||
unsigned getCompoundOp(MCInst const &HMCI) {
|
||||
static unsigned getCompoundOp(MCInst const &HMCI) {
|
||||
const MCOperand &Predicate = HMCI.getOperand(0);
|
||||
unsigned PredReg = Predicate.getReg();
|
||||
|
||||
@ -198,11 +193,10 @@ unsigned getCompoundOp(MCInst const &HMCI) {
|
||||
return (PredReg == Hexagon::P0) ? tp0_jump_t : tp1_jump_t;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R) {
|
||||
MCInst *CompoundInsn = 0;
|
||||
static MCInst *getCompoundInsn(MCContext &Context, MCInst const &L,
|
||||
MCInst const &R) {
|
||||
MCInst *CompoundInsn = nullptr;
|
||||
unsigned compoundOpcode;
|
||||
MCOperand Rs, Rt;
|
||||
int64_t Value;
|
||||
@ -336,12 +330,10 @@ MCInst *getCompoundInsn(MCContext &Context, MCInst const &L, MCInst const &R) {
|
||||
|
||||
return CompoundInsn;
|
||||
}
|
||||
}
|
||||
|
||||
/// Non-Symmetrical. See if these two instructions are fit for compound pair.
|
||||
namespace {
|
||||
bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
|
||||
MCInst const &MIb, bool IsExtendedB) {
|
||||
static bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
|
||||
MCInst const &MIb, bool IsExtendedB) {
|
||||
unsigned MIaG = getCompoundCandidateGroup(MIa, IsExtendedA);
|
||||
unsigned MIbG = getCompoundCandidateGroup(MIb, IsExtendedB);
|
||||
// We have two candidates - check that this is the same register
|
||||
@ -353,10 +345,9 @@ bool isOrderedCompoundPair(MCInst const &MIa, bool IsExtendedA,
|
||||
return ((MIaG == HexagonII::HCG_A && MIbG == HexagonII::HCG_B) &&
|
||||
(MIa.getOperand(0).getReg() == MIb.getOperand(0).getReg()));
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI) {
|
||||
static bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context,
|
||||
MCInst &MCI) {
|
||||
assert(HexagonMCInstrInfo::isBundle(MCI));
|
||||
bool JExtended = false;
|
||||
for (MCInst::iterator J =
|
||||
@ -367,8 +358,7 @@ bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI) {
|
||||
JExtended = true;
|
||||
continue;
|
||||
}
|
||||
if (llvm::HexagonMCInstrInfo::getType(MCII, *JumpInst) ==
|
||||
HexagonII::TypeJ) {
|
||||
if (HexagonMCInstrInfo::getType(MCII, *JumpInst) == HexagonII::TypeJ) {
|
||||
// Try to pair with another insn (B)undled with jump.
|
||||
bool BExtended = false;
|
||||
for (MCInst::iterator B =
|
||||
@ -401,7 +391,6 @@ bool lookForCompound(MCInstrInfo const &MCII, MCContext &Context, MCInst &MCI) {
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/// tryCompound - Given a bundle check for compound insns when one
|
||||
/// is found update the contents fo the bundle with the compound insn.
|
||||
@ -420,6 +409,4 @@ void HexagonMCInstrInfo::tryCompound(MCInstrInfo const &MCII,
|
||||
// a compound is found.
|
||||
while (lookForCompound(MCII, Context, MCI))
|
||||
;
|
||||
|
||||
return;
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- RDFCopy.h --------------------------------------------------------===//
|
||||
//===--- RDFCopy.h ----------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -7,23 +7,26 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef RDF_COPY_H
|
||||
#define RDF_COPY_H
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_RDFCOPY_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_RDFCOPY_H
|
||||
|
||||
#include "RDFGraph.h"
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MachineBasicBlock;
|
||||
class MachineDominatorTree;
|
||||
class MachineInstr;
|
||||
|
||||
namespace rdf {
|
||||
|
||||
struct CopyPropagation {
|
||||
CopyPropagation(DataFlowGraph &dfg) : MDT(dfg.getDT()), DFG(dfg),
|
||||
Trace(false) {}
|
||||
virtual ~CopyPropagation() {}
|
||||
|
||||
virtual ~CopyPropagation() = default;
|
||||
|
||||
bool run();
|
||||
void trace(bool On) { Trace = On; }
|
||||
@ -49,7 +52,9 @@ namespace rdf {
|
||||
void updateMap(NodeAddr<InstrNode*> IA);
|
||||
bool scanBlock(MachineBasicBlock *B);
|
||||
};
|
||||
} // namespace rdf
|
||||
} // namespace llvm
|
||||
|
||||
#endif
|
||||
} // end namespace rdf
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_RDFCOPY_H
|
||||
|
@ -10,16 +10,31 @@
|
||||
// Target-independent, SSA-based data flow graph for register data flow (RDF).
|
||||
//
|
||||
#include "RDFGraph.h"
|
||||
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineDominanceFrontier.h"
|
||||
#include "llvm/CodeGen/MachineDominators.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/IR/Function.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetLowering.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
using namespace rdf;
|
||||
@ -88,14 +103,12 @@ raw_ostream &operator<< (raw_ostream &OS, const Print<NodeId> &P) {
|
||||
return OS;
|
||||
}
|
||||
|
||||
namespace {
|
||||
void printRefHeader(raw_ostream &OS, const NodeAddr<RefNode*> RA,
|
||||
const DataFlowGraph &G) {
|
||||
OS << Print<NodeId>(RA.Id, G) << '<'
|
||||
<< Print<RegisterRef>(RA.Addr->getRegRef(G), G) << '>';
|
||||
if (RA.Addr->getFlags() & NodeAttrs::Fixed)
|
||||
OS << '!';
|
||||
}
|
||||
static void printRefHeader(raw_ostream &OS, const NodeAddr<RefNode*> RA,
|
||||
const DataFlowGraph &G) {
|
||||
OS << Print<NodeId>(RA.Id, G) << '<'
|
||||
<< Print<RegisterRef>(RA.Addr->getRegRef(G), G) << '>';
|
||||
if (RA.Addr->getFlags() & NodeAttrs::Fixed)
|
||||
OS << '!';
|
||||
}
|
||||
|
||||
template<>
|
||||
@ -183,9 +196,11 @@ raw_ostream &operator<< (raw_ostream &OS, const Print<NodeSet> &P) {
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
template <typename T>
|
||||
struct PrintListV {
|
||||
PrintListV(const NodeList &L, const DataFlowGraph &G) : List(L), G(G) {}
|
||||
|
||||
typedef T Type;
|
||||
const NodeList &List;
|
||||
const DataFlowGraph &G;
|
||||
@ -201,7 +216,8 @@ namespace {
|
||||
}
|
||||
return OS;
|
||||
}
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
template<>
|
||||
raw_ostream &operator<< (raw_ostream &OS, const Print<NodeAddr<PhiNode*>> &P) {
|
||||
@ -219,10 +235,10 @@ raw_ostream &operator<< (raw_ostream &OS,
|
||||
// Print the target for calls and branches (for readability).
|
||||
if (MI.isCall() || MI.isBranch()) {
|
||||
MachineInstr::const_mop_iterator T =
|
||||
find_if(MI.operands(),
|
||||
[] (const MachineOperand &Op) -> bool {
|
||||
return Op.isMBB() || Op.isGlobal() || Op.isSymbol();
|
||||
});
|
||||
llvm::find_if(MI.operands(),
|
||||
[] (const MachineOperand &Op) -> bool {
|
||||
return Op.isMBB() || Op.isGlobal() || Op.isSymbol();
|
||||
});
|
||||
if (T != MI.operands_end()) {
|
||||
OS << ' ';
|
||||
if (T->isMBB())
|
||||
@ -327,8 +343,8 @@ raw_ostream &operator<< (raw_ostream &OS,
|
||||
return OS;
|
||||
}
|
||||
|
||||
} // namespace rdf
|
||||
} // namespace llvm
|
||||
} // end namespace rdf
|
||||
} // end namespace llvm
|
||||
|
||||
// Node allocation functions.
|
||||
//
|
||||
@ -390,7 +406,6 @@ void NodeAllocator::clear() {
|
||||
ActiveEnd = nullptr;
|
||||
}
|
||||
|
||||
|
||||
// Insert node NA after "this" in the circular chain.
|
||||
void NodeBase::append(NodeAddr<NodeBase*> NA) {
|
||||
NodeId Nx = Next;
|
||||
@ -401,7 +416,6 @@ void NodeBase::append(NodeAddr<NodeBase*> NA) {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Fundamental node manipulator functions.
|
||||
|
||||
// Obtain the register reference from a reference node.
|
||||
@ -590,7 +604,6 @@ NodeAddr<BlockNode*> FuncNode::getEntryBlock(const DataFlowGraph &G) {
|
||||
return findBlock(EntryB, G);
|
||||
}
|
||||
|
||||
|
||||
// Target operand information.
|
||||
//
|
||||
|
||||
@ -641,7 +654,6 @@ bool TargetOperandInfo::isFixedReg(const MachineInstr &In, unsigned OpNum)
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
RegisterRef RegisterAggr::normalize(RegisterRef RR) const {
|
||||
RegisterId SuperReg = RR.Reg;
|
||||
while (true) {
|
||||
@ -745,7 +757,6 @@ void RegisterAggr::print(raw_ostream &OS) const {
|
||||
OS << " }";
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
// The data flow graph construction.
|
||||
//
|
||||
@ -753,10 +764,9 @@ void RegisterAggr::print(raw_ostream &OS) const {
|
||||
DataFlowGraph::DataFlowGraph(MachineFunction &mf, const TargetInstrInfo &tii,
|
||||
const TargetRegisterInfo &tri, const MachineDominatorTree &mdt,
|
||||
const MachineDominanceFrontier &mdf, const TargetOperandInfo &toi)
|
||||
: LMI(), MF(mf), TII(tii), TRI(tri), MDT(mdt), MDF(mdf), TOI(toi) {
|
||||
: MF(mf), TII(tii), TRI(tri), MDT(mdt), MDF(mdf), TOI(toi) {
|
||||
}
|
||||
|
||||
|
||||
// The implementation of the definition stack.
|
||||
// Each register reference has its own definition stack. In particular,
|
||||
// for a register references "Reg" and "Reg:subreg" will each have their
|
||||
@ -845,7 +855,6 @@ unsigned DataFlowGraph::DefStack::nextDown(unsigned P) const {
|
||||
return P;
|
||||
}
|
||||
|
||||
|
||||
// Register information.
|
||||
|
||||
// Get the list of references aliased to RR. Lane masks are ignored.
|
||||
@ -915,7 +924,6 @@ NodeAddr<NodeBase*> DataFlowGraph::cloneNode(const NodeAddr<NodeBase*> B) {
|
||||
return NA;
|
||||
}
|
||||
|
||||
|
||||
// Allocation routines for specific node types/kinds.
|
||||
|
||||
NodeAddr<UseNode*> DataFlowGraph::newUse(NodeAddr<InstrNode*> Owner,
|
||||
@ -1248,7 +1256,6 @@ bool DataFlowGraph::alias(RegisterRef RA, RegisterRef RB) const {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// Clear all information in the graph.
|
||||
void DataFlowGraph::reset() {
|
||||
Memory.clear();
|
||||
@ -1256,7 +1263,6 @@ void DataFlowGraph::reset() {
|
||||
Func = NodeAddr<FuncNode*>();
|
||||
}
|
||||
|
||||
|
||||
// Return the next reference node in the instruction node IA that is related
|
||||
// to RA. Conceptually, two reference nodes are related if they refer to the
|
||||
// same instance of a register access, but differ in flags or other minor
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- RDFGraph.h -------------------------------------------------------===//
|
||||
//===--- RDFGraph.h ---------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -221,20 +221,25 @@
|
||||
// The statement s5 has two use nodes for t0: u7" and u9". The quotation
|
||||
// mark " indicates that the node is a shadow.
|
||||
//
|
||||
#ifndef RDF_GRAPH_H
|
||||
#define RDF_GRAPH_H
|
||||
|
||||
#ifndef LLVM_LIB_TARGET_HEXAGON_RDFGRAPH_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_RDFGRAPH_H
|
||||
|
||||
#include "llvm/ADT/BitVector.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/MC/LaneBitmask.h"
|
||||
#include "llvm/Support/Allocator.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Support/Timer.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <functional>
|
||||
#include <map>
|
||||
#include <set>
|
||||
#include <unordered_map>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
// RDF uses uint32_t to refer to registers. This is to ensure that the type
|
||||
@ -243,6 +248,7 @@
|
||||
static_assert(sizeof(uint32_t) == sizeof(unsigned), "Those should be equal");
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class MachineBasicBlock;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
@ -252,6 +258,7 @@ namespace llvm {
|
||||
class TargetInstrInfo;
|
||||
|
||||
namespace rdf {
|
||||
|
||||
typedef uint32_t NodeId;
|
||||
typedef uint32_t RegisterId;
|
||||
|
||||
@ -293,9 +300,11 @@ namespace rdf {
|
||||
static uint16_t set_type(uint16_t A, uint16_t T) {
|
||||
return (A & ~TypeMask) | T;
|
||||
}
|
||||
|
||||
static uint16_t set_kind(uint16_t A, uint16_t K) {
|
||||
return (A & ~KindMask) | K;
|
||||
}
|
||||
|
||||
static uint16_t set_flags(uint16_t A, uint16_t F) {
|
||||
return (A & ~FlagMask) | F;
|
||||
}
|
||||
@ -326,9 +335,14 @@ namespace rdf {
|
||||
};
|
||||
|
||||
template <typename T> struct NodeAddr {
|
||||
NodeAddr() : Addr(nullptr), Id(0) {}
|
||||
NodeAddr() : Addr(nullptr) {}
|
||||
NodeAddr(T A, NodeId I) : Addr(A), Id(I) {}
|
||||
|
||||
// Type cast (casting constructor). The reason for having this class
|
||||
// instead of std::pair.
|
||||
template <typename S> NodeAddr(const NodeAddr<S> &NA)
|
||||
: Addr(static_cast<T>(NA.Addr)), Id(NA.Id) {}
|
||||
|
||||
bool operator== (const NodeAddr<T> &NA) const {
|
||||
assert((Addr == NA.Addr) == (Id == NA.Id));
|
||||
return Addr == NA.Addr;
|
||||
@ -336,13 +350,9 @@ namespace rdf {
|
||||
bool operator!= (const NodeAddr<T> &NA) const {
|
||||
return !operator==(NA);
|
||||
}
|
||||
// Type cast (casting constructor). The reason for having this class
|
||||
// instead of std::pair.
|
||||
template <typename S> NodeAddr(const NodeAddr<S> &NA)
|
||||
: Addr(static_cast<T>(NA.Addr)), Id(NA.Id) {}
|
||||
|
||||
T Addr;
|
||||
NodeId Id;
|
||||
NodeId Id = 0;
|
||||
};
|
||||
|
||||
struct NodeBase;
|
||||
@ -366,17 +376,20 @@ namespace rdf {
|
||||
struct NodeAllocator {
|
||||
// Amount of storage for a single node.
|
||||
enum { NodeMemSize = 32 };
|
||||
|
||||
NodeAllocator(uint32_t NPB = 4096)
|
||||
: NodesPerBlock(NPB), BitsPerIndex(Log2_32(NPB)),
|
||||
IndexMask((1 << BitsPerIndex)-1), ActiveEnd(nullptr) {
|
||||
IndexMask((1 << BitsPerIndex)-1) {
|
||||
assert(isPowerOf2_32(NPB));
|
||||
}
|
||||
|
||||
NodeBase *ptr(NodeId N) const {
|
||||
uint32_t N1 = N-1;
|
||||
uint32_t BlockN = N1 >> BitsPerIndex;
|
||||
uint32_t Offset = (N1 & IndexMask) * NodeMemSize;
|
||||
return reinterpret_cast<NodeBase*>(Blocks[BlockN]+Offset);
|
||||
}
|
||||
|
||||
NodeId id(const NodeBase *P) const;
|
||||
NodeAddr<NodeBase*> New();
|
||||
void clear();
|
||||
@ -384,6 +397,7 @@ namespace rdf {
|
||||
private:
|
||||
void startNewBlock();
|
||||
bool needNewBlock();
|
||||
|
||||
uint32_t makeId(uint32_t Block, uint32_t Index) const {
|
||||
// Add 1 to the id, to avoid the id of 0, which is treated as "null".
|
||||
return ((Block << BitsPerIndex) | Index) + 1;
|
||||
@ -392,7 +406,7 @@ namespace rdf {
|
||||
const uint32_t NodesPerBlock;
|
||||
const uint32_t BitsPerIndex;
|
||||
const uint32_t IndexMask;
|
||||
char *ActiveEnd;
|
||||
char *ActiveEnd = nullptr;
|
||||
std::vector<char*> Blocks;
|
||||
typedef BumpPtrAllocatorImpl<MallocAllocator, 65536> AllocatorTy;
|
||||
AllocatorTy MemPool;
|
||||
@ -405,6 +419,7 @@ namespace rdf {
|
||||
RegisterRef() : RegisterRef(0) {}
|
||||
explicit RegisterRef(RegisterId R, LaneBitmask M = LaneBitmask::getAll())
|
||||
: Reg(R), Mask(R != 0 ? M : LaneBitmask::getNone()) {}
|
||||
|
||||
operator bool() const { return Reg != 0 && Mask.any(); }
|
||||
bool operator== (const RegisterRef &RR) const {
|
||||
return Reg == RR.Reg && Mask == RR.Mask;
|
||||
@ -420,7 +435,8 @@ namespace rdf {
|
||||
|
||||
struct TargetOperandInfo {
|
||||
TargetOperandInfo(const TargetInstrInfo &tii) : TII(tii) {}
|
||||
virtual ~TargetOperandInfo() {}
|
||||
virtual ~TargetOperandInfo() = default;
|
||||
|
||||
virtual bool isPreserving(const MachineInstr &In, unsigned OpNum) const;
|
||||
virtual bool isClobbering(const MachineInstr &In, unsigned OpNum) const;
|
||||
virtual bool isFixedReg(const MachineInstr &In, unsigned OpNum) const;
|
||||
@ -428,7 +444,6 @@ namespace rdf {
|
||||
const TargetInstrInfo &TII;
|
||||
};
|
||||
|
||||
|
||||
// Packed register reference. Only used for storage.
|
||||
struct PackedRegisterRef {
|
||||
RegisterId Reg;
|
||||
@ -442,11 +457,13 @@ namespace rdf {
|
||||
template <typename T, unsigned N = 32>
|
||||
struct IndexedSet {
|
||||
IndexedSet() : Map() { Map.reserve(N); }
|
||||
|
||||
T get(uint32_t Idx) const {
|
||||
// Index Idx corresponds to Map[Idx-1].
|
||||
assert(Idx != 0 && !Map.empty() && Idx-1 < Map.size());
|
||||
return Map[Idx-1];
|
||||
}
|
||||
|
||||
uint32_t insert(T Val) {
|
||||
// Linear search.
|
||||
auto F = llvm::find(Map, Val);
|
||||
@ -455,11 +472,13 @@ namespace rdf {
|
||||
Map.push_back(Val);
|
||||
return Map.size(); // Return actual_index + 1.
|
||||
}
|
||||
|
||||
uint32_t find(T Val) const {
|
||||
auto F = llvm::find(Map, Val);
|
||||
assert(F != Map.end());
|
||||
return F - Map.begin();
|
||||
}
|
||||
|
||||
private:
|
||||
std::vector<T> Map;
|
||||
};
|
||||
@ -478,12 +497,14 @@ namespace rdf {
|
||||
assert(LM.any());
|
||||
return LM.all() ? 0 : find(LM);
|
||||
}
|
||||
|
||||
PackedRegisterRef pack(RegisterRef RR) {
|
||||
return { RR.Reg, getIndexForLaneMask(RR.Mask) };
|
||||
}
|
||||
PackedRegisterRef pack(RegisterRef RR) const {
|
||||
return { RR.Reg, getIndexForLaneMask(RR.Mask) };
|
||||
}
|
||||
|
||||
RegisterRef unpack(PackedRegisterRef PR) const {
|
||||
return RegisterRef(PR.Reg, getLaneMaskForIndex(PR.MaskId));
|
||||
}
|
||||
@ -491,11 +512,8 @@ namespace rdf {
|
||||
|
||||
struct RegisterAggr {
|
||||
RegisterAggr(const TargetRegisterInfo &tri)
|
||||
: Masks(), ExpAliasUnits(tri.getNumRegUnits()), CheckUnits(false),
|
||||
TRI(tri) {}
|
||||
RegisterAggr(const RegisterAggr &RG)
|
||||
: Masks(RG.Masks), ExpAliasUnits(RG.ExpAliasUnits),
|
||||
CheckUnits(RG.CheckUnits), TRI(RG.TRI) {}
|
||||
: ExpAliasUnits(tri.getNumRegUnits()), CheckUnits(false), TRI(tri) {}
|
||||
RegisterAggr(const RegisterAggr &RG) = default;
|
||||
|
||||
bool empty() const { return Masks.empty(); }
|
||||
bool hasAliasOf(RegisterRef RR) const;
|
||||
@ -530,11 +548,11 @@ namespace rdf {
|
||||
const TargetRegisterInfo &TRI;
|
||||
};
|
||||
|
||||
|
||||
struct NodeBase {
|
||||
public:
|
||||
// Make sure this is a POD.
|
||||
NodeBase() = default;
|
||||
|
||||
uint16_t getType() const { return NodeAttrs::type(Attrs); }
|
||||
uint16_t getKind() const { return NodeAttrs::kind(Attrs); }
|
||||
uint16_t getFlags() const { return NodeAttrs::flags(Attrs); }
|
||||
@ -596,29 +614,36 @@ namespace rdf {
|
||||
|
||||
struct RefNode : public NodeBase {
|
||||
RefNode() = default;
|
||||
|
||||
RegisterRef getRegRef(const DataFlowGraph &G) const;
|
||||
|
||||
MachineOperand &getOp() {
|
||||
assert(!(getFlags() & NodeAttrs::PhiRef));
|
||||
return *Ref.Op;
|
||||
}
|
||||
|
||||
void setRegRef(RegisterRef RR, DataFlowGraph &G);
|
||||
void setRegRef(MachineOperand *Op, DataFlowGraph &G);
|
||||
|
||||
NodeId getReachingDef() const {
|
||||
return Ref.RD;
|
||||
}
|
||||
void setReachingDef(NodeId RD) {
|
||||
Ref.RD = RD;
|
||||
}
|
||||
|
||||
NodeId getSibling() const {
|
||||
return Ref.Sib;
|
||||
}
|
||||
void setSibling(NodeId Sib) {
|
||||
Ref.Sib = Sib;
|
||||
}
|
||||
|
||||
bool isUse() const {
|
||||
assert(getType() == NodeAttrs::Ref);
|
||||
return getKind() == NodeAttrs::Use;
|
||||
}
|
||||
|
||||
bool isDef() const {
|
||||
assert(getType() == NodeAttrs::Ref);
|
||||
return getKind() == NodeAttrs::Def;
|
||||
@ -702,6 +727,7 @@ namespace rdf {
|
||||
MachineBasicBlock *getCode() const {
|
||||
return CodeNode::getCode<MachineBasicBlock*>();
|
||||
}
|
||||
|
||||
void addPhi(NodeAddr<PhiNode*> PA, const DataFlowGraph &G);
|
||||
};
|
||||
|
||||
@ -709,6 +735,7 @@ namespace rdf {
|
||||
MachineFunction *getCode() const {
|
||||
return CodeNode::getCode<MachineFunction*>();
|
||||
}
|
||||
|
||||
NodeAddr<BlockNode*> findBlock(const MachineBasicBlock *BB,
|
||||
const DataFlowGraph &G) const;
|
||||
NodeAddr<BlockNode*> getEntryBlock(const DataFlowGraph &G);
|
||||
@ -723,6 +750,7 @@ namespace rdf {
|
||||
template <typename T> T ptr(NodeId N) const {
|
||||
return static_cast<T>(ptr(N));
|
||||
}
|
||||
|
||||
NodeId id(const NodeBase *P) const;
|
||||
|
||||
template <typename T> NodeAddr<T> addr(NodeId N) const {
|
||||
@ -738,13 +766,17 @@ namespace rdf {
|
||||
|
||||
struct DefStack {
|
||||
DefStack() = default;
|
||||
|
||||
bool empty() const { return Stack.empty() || top() == bottom(); }
|
||||
|
||||
private:
|
||||
typedef NodeAddr<DefNode*> value_type;
|
||||
struct Iterator {
|
||||
typedef DefStack::value_type value_type;
|
||||
|
||||
Iterator &up() { Pos = DS.nextUp(Pos); return *this; }
|
||||
Iterator &down() { Pos = DS.nextDown(Pos); return *this; }
|
||||
|
||||
value_type operator*() const {
|
||||
assert(Pos >= 1);
|
||||
return DS.Stack[Pos-1];
|
||||
@ -755,14 +787,17 @@ namespace rdf {
|
||||
}
|
||||
bool operator==(const Iterator &It) const { return Pos == It.Pos; }
|
||||
bool operator!=(const Iterator &It) const { return Pos != It.Pos; }
|
||||
|
||||
private:
|
||||
Iterator(const DefStack &S, bool Top);
|
||||
|
||||
// Pos-1 is the index in the StorageType object that corresponds to
|
||||
// the top of the DefStack.
|
||||
const DefStack &DS;
|
||||
unsigned Pos;
|
||||
friend struct DefStack;
|
||||
};
|
||||
|
||||
public:
|
||||
typedef Iterator iterator;
|
||||
iterator top() const { return Iterator(*this, true); }
|
||||
@ -773,14 +808,18 @@ namespace rdf {
|
||||
void pop();
|
||||
void start_block(NodeId N);
|
||||
void clear_block(NodeId N);
|
||||
|
||||
private:
|
||||
friend struct Iterator;
|
||||
typedef std::vector<value_type> StorageType;
|
||||
|
||||
bool isDelimiter(const StorageType::value_type &P, NodeId N = 0) const {
|
||||
return (P.Addr == nullptr) && (N == 0 || P.Id == N);
|
||||
}
|
||||
|
||||
unsigned nextUp(unsigned P) const;
|
||||
unsigned nextDown(unsigned P) const;
|
||||
|
||||
StorageType Stack;
|
||||
};
|
||||
|
||||
@ -819,6 +858,7 @@ namespace rdf {
|
||||
if (RemoveFromOwner)
|
||||
removeFromOwner(UA);
|
||||
}
|
||||
|
||||
void unlinkDef(NodeAddr<DefNode*> DA, bool RemoveFromOwner) {
|
||||
unlinkDefDF(DA);
|
||||
if (RemoveFromOwner)
|
||||
@ -831,23 +871,28 @@ namespace rdf {
|
||||
return BA.Addr->getType() == NodeAttrs::Ref &&
|
||||
BA.Addr->getKind() == Kind;
|
||||
}
|
||||
|
||||
template <uint16_t Kind>
|
||||
static bool IsCode(const NodeAddr<NodeBase*> BA) {
|
||||
return BA.Addr->getType() == NodeAttrs::Code &&
|
||||
BA.Addr->getKind() == Kind;
|
||||
}
|
||||
|
||||
static bool IsDef(const NodeAddr<NodeBase*> BA) {
|
||||
return BA.Addr->getType() == NodeAttrs::Ref &&
|
||||
BA.Addr->getKind() == NodeAttrs::Def;
|
||||
}
|
||||
|
||||
static bool IsUse(const NodeAddr<NodeBase*> BA) {
|
||||
return BA.Addr->getType() == NodeAttrs::Ref &&
|
||||
BA.Addr->getKind() == NodeAttrs::Use;
|
||||
}
|
||||
|
||||
static bool IsPhi(const NodeAddr<NodeBase*> BA) {
|
||||
return BA.Addr->getType() == NodeAttrs::Code &&
|
||||
BA.Addr->getKind() == NodeAttrs::Phi;
|
||||
}
|
||||
|
||||
static bool IsPreservingDef(const NodeAddr<DefNode*> DA) {
|
||||
uint16_t Flags = DA.Addr->getFlags();
|
||||
return (Flags & NodeAttrs::Preserving) && !(Flags & NodeAttrs::Undef);
|
||||
@ -902,6 +947,7 @@ namespace rdf {
|
||||
|
||||
void unlinkUseDF(NodeAddr<UseNode*> UA);
|
||||
void unlinkDefDF(NodeAddr<DefNode*> DA);
|
||||
|
||||
void removeFromOwner(NodeAddr<RefNode*> RA) {
|
||||
NodeAddr<InstrNode*> IA = RA.Addr->getOwner(*this);
|
||||
IA.Addr->removeMember(RA, *this);
|
||||
@ -967,7 +1013,6 @@ namespace rdf {
|
||||
return MM;
|
||||
}
|
||||
|
||||
|
||||
// Optionally print the lane mask, if it is not ~0.
|
||||
struct PrintLaneMaskOpt {
|
||||
PrintLaneMaskOpt(LaneBitmask M) : Mask(M) {}
|
||||
@ -991,7 +1036,9 @@ namespace rdf {
|
||||
PrintNode(const NodeAddr<T> &x, const DataFlowGraph &g)
|
||||
: Print<NodeAddr<T>>(x, g) {}
|
||||
};
|
||||
} // namespace rdf
|
||||
} // namespace llvm
|
||||
|
||||
#endif // RDF_GRAPH_H
|
||||
} // end namespace rdf
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_RDFGRAPH_H
|
||||
|
Loading…
Reference in New Issue
Block a user