1
0
mirror of https://github.com/RPCS3/llvm-mirror.git synced 2024-11-26 04:32:44 +01:00

[Hexagon] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).

llvm-svn: 289604
This commit is contained in:
Eugene Zelenko 2016-12-13 22:13:50 +00:00
parent 4a5c82b02b
commit 271b3b84f5
7 changed files with 360 additions and 403 deletions

View File

@ -10,39 +10,53 @@
#define DEBUG_TYPE "mcasmparser"
#include "Hexagon.h"
#include "HexagonRegisterInfo.h"
#include "HexagonTargetStreamer.h"
#include "MCTargetDesc/HexagonBaseInfo.h"
#include "MCTargetDesc/HexagonMCAsmInfo.h"
#include "MCTargetDesc/HexagonMCChecker.h"
#include "MCTargetDesc/HexagonMCELFStreamer.h"
#include "MCTargetDesc/HexagonMCExpr.h"
#include "MCTargetDesc/HexagonMCShuffler.h"
#include "MCTargetDesc/HexagonMCInstrInfo.h"
#include "MCTargetDesc/HexagonMCTargetDesc.h"
#include "MCTargetDesc/HexagonShuffler.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/ADT/Twine.h"
#include "llvm/MC/MCAssembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCDirectives.h"
#include "llvm/MC/MCELFStreamer.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCParser/MCAsmLexer.h"
#include "llvm/MC/MCParser/MCAsmParser.h"
#include "llvm/MC/MCParser/MCAsmParserExtension.h"
#include "llvm/MC/MCParser/MCParsedAsmOperand.h"
#include "llvm/MC/MCParser/MCTargetAsmParser.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSectionELF.h"
#include "llvm/MC/MCStreamer.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/MC/MCSymbol.h"
#include "llvm/MC/MCValue.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ELF.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Format.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/SourceMgr.h"
#include "llvm/Support/TargetRegistry.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/SMLoc.h"
#include "llvm/Support/TargetRegistry.h"
#include <algorithm>
#include <cassert>
#include <cctype>
#include <cstddef>
#include <cstdint>
#include <memory>
#include <string>
#include <utility>
using namespace llvm;
@ -65,8 +79,8 @@ static cl::opt<bool> ErrorNoncontigiousRegister("merror-noncontigious-register",
cl::desc("Error for register names that aren't contigious"),
cl::init(false));
namespace {
struct HexagonOperand;
class HexagonAsmParser : public MCTargetAsmParser {
@ -93,9 +107,7 @@ class HexagonAsmParser : public MCTargetAsmParser {
bool Error(SMLoc L, const Twine &Msg) { return Parser.Error(L, Msg); }
bool ParseDirectiveFalign(unsigned Size, SMLoc L);
virtual bool ParseRegister(unsigned &RegNo,
SMLoc &StartLoc,
SMLoc &EndLoc) override;
bool ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &EndLoc) override;
bool ParseDirectiveSubsection(SMLoc L);
bool ParseDirectiveValue(unsigned Size, SMLoc L);
bool ParseDirectiveComm(bool IsLocal, SMLoc L);
@ -141,14 +153,14 @@ public:
MCII (MII), MCB(HexagonMCInstrInfo::createBundle()), InBrackets(false) {
setAvailableFeatures(ComputeAvailableFeatures(getSTI().getFeatureBits()));
MCAsmParserExtension::Initialize(_Parser);
MCAsmParserExtension::Initialize(_Parser);
Assembler = nullptr;
// FIXME: need better way to detect AsmStreamer (upstream removed getKind())
if (!Parser.getStreamer().hasRawTextSupport()) {
MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
Assembler = &MES->getAssembler();
}
Assembler = nullptr;
// FIXME: need better way to detect AsmStreamer (upstream removed getKind())
if (!Parser.getStreamer().hasRawTextSupport()) {
MCELFStreamer *MES = static_cast<MCELFStreamer *>(&Parser.getStreamer());
Assembler = &MES->getAssembler();
}
}
bool splitIdentifier(OperandVector &Operands);
@ -157,15 +169,17 @@ public:
bool implicitExpressionLocation(OperandVector &Operands);
bool parseExpressionOrOperand(OperandVector &Operands);
bool parseExpression(MCExpr const *& Expr);
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) override
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
SMLoc NameLoc, OperandVector &Operands) override
{
llvm_unreachable("Unimplemented");
}
virtual bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name,
AsmToken ID, OperandVector &Operands) override;
virtual bool ParseDirective(AsmToken DirectiveID) override;
bool ParseInstruction(ParseInstructionInfo &Info, StringRef Name, AsmToken ID,
OperandVector &Operands) override;
bool ParseDirective(AsmToken DirectiveID) override;
};
/// HexagonOperand - Instances of this class represent a parsed Hexagon machine
@ -219,12 +233,12 @@ public:
}
/// getStartLoc - Get the location of the first token of this operand.
SMLoc getStartLoc() const { return StartLoc; }
SMLoc getStartLoc() const override { return StartLoc; }
/// getEndLoc - Get the location of the last token of this operand.
SMLoc getEndLoc() const { return EndLoc; }
SMLoc getEndLoc() const override { return EndLoc; }
unsigned getReg() const {
unsigned getReg() const override {
assert(Kind == Register && "Invalid access!");
return Reg.RegNum;
}
@ -234,10 +248,10 @@ public:
return Imm.Val;
}
bool isToken() const { return Kind == Token; }
bool isImm() const { return Kind == Immediate; }
bool isMem() const { llvm_unreachable("No isMem"); }
bool isReg() const { return Kind == Register; }
bool isToken() const override { return Kind == Token; }
bool isImm() const override { return Kind == Immediate; }
bool isMem() const override { llvm_unreachable("No isMem"); }
bool isReg() const override { return Kind == Register; }
bool CheckImmRange(int immBits, int zeroBits, bool isSigned,
bool isRelocatable, bool Extendable) const {
@ -259,11 +273,11 @@ public:
if (bits == 64)
return true;
if (Res >= 0)
return ((uint64_t)Res < (uint64_t)(1ULL << bits)) ? true : false;
return ((uint64_t)Res < (uint64_t)(1ULL << bits));
else {
const int64_t high_bit_set = 1ULL << 63;
const uint64_t mask = (high_bit_set >> (63 - bits));
return (((uint64_t)Res & mask) == mask) ? true : false;
return (((uint64_t)Res & mask) == mask);
}
}
} else if (myMCExpr->getKind() == MCExpr::SymbolRef && isRelocatable)
@ -565,7 +579,7 @@ public:
return StringRef(Tok.Data, Tok.Length);
}
virtual void print(raw_ostream &OS) const;
void print(raw_ostream &OS) const override;
static std::unique_ptr<HexagonOperand> CreateToken(StringRef Str, SMLoc S) {
HexagonOperand *Op = new HexagonOperand(Token);
@ -595,7 +609,7 @@ public:
}
};
} // end anonymous namespace.
} // end anonymous namespace
void HexagonOperand::print(raw_ostream &OS) const {
switch (Kind) {
@ -625,7 +639,7 @@ bool HexagonAsmParser::finishBundle(SMLoc IDLoc, MCStreamer &Out) {
getContext(), MCB,
&Check);
while (Check.getNextErrInfo() == true) {
while (Check.getNextErrInfo()) {
unsigned Reg = Check.getErrRegister();
Twine R(RI->getName(Reg));
@ -876,7 +890,7 @@ bool HexagonAsmParser::ParseDirective(AsmToken DirectiveID) {
return true;
}
bool HexagonAsmParser::ParseDirectiveSubsection(SMLoc L) {
const MCExpr *Subsection = 0;
const MCExpr *Subsection = nullptr;
int64_t Res;
assert((getLexer().isNot(AsmToken::EndOfStatement)) &&
@ -912,7 +926,7 @@ bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
SMLoc ExprLoc = L;
// Make sure we have a number (false is returned if expression is a number)
if (getParser().parseExpression(Value) == false) {
if (!getParser().parseExpression(Value)) {
// Make sure this is a number that is in range
const MCConstantExpr *MCE = dyn_cast<MCConstantExpr>(Value);
uint64_t IntValue = MCE->getValue();
@ -934,8 +948,7 @@ bool HexagonAsmParser::ParseDirectiveFalign(unsigned Size, SMLoc L) {
/// ::= .word [ expression (, expression)* ]
bool HexagonAsmParser::ParseDirectiveValue(unsigned Size, SMLoc L) {
if (getLexer().isNot(AsmToken::EndOfStatement)) {
for (;;) {
while (true) {
const MCExpr *Value;
SMLoc ExprLoc = L;
if (getParser().parseExpression(Value))
@ -1067,8 +1080,8 @@ extern "C" void LLVMInitializeHexagonAsmParser() {
#define GET_REGISTER_MATCHER
#include "HexagonGenAsmMatcher.inc"
namespace {
bool previousEqual(OperandVector &Operands, size_t Index, StringRef String) {
static bool previousEqual(OperandVector &Operands, size_t Index,
StringRef String) {
if (Index >= Operands.size())
return false;
MCParsedAsmOperand &Operand = *Operands[Operands.size() - Index - 1];
@ -1076,14 +1089,14 @@ bool previousEqual(OperandVector &Operands, size_t Index, StringRef String) {
return false;
return static_cast<HexagonOperand &>(Operand).getToken().equals_lower(String);
}
bool previousIsLoop(OperandVector &Operands, size_t Index) {
static bool previousIsLoop(OperandVector &Operands, size_t Index) {
return previousEqual(Operands, Index, "loop0") ||
previousEqual(Operands, Index, "loop1") ||
previousEqual(Operands, Index, "sp1loop0") ||
previousEqual(Operands, Index, "sp2loop0") ||
previousEqual(Operands, Index, "sp3loop0");
}
}
bool HexagonAsmParser::splitIdentifier(OperandVector &Operands) {
AsmToken const &Token = getParser().getTok();
@ -1172,7 +1185,7 @@ bool HexagonAsmParser::isLabel(AsmToken &Token) {
StringRef Raw (String.data(), Third.getString().data() - String.data() +
Third.getString().size());
std::string Collapsed = Raw;
Collapsed.erase(remove_if(Collapsed, isspace), Collapsed.end());
Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
StringRef Whole = Collapsed;
std::pair<StringRef, StringRef> DotSplit = Whole.split('.');
if (!matchRegister(DotSplit.first.lower()))
@ -1216,7 +1229,7 @@ bool HexagonAsmParser::ParseRegister(unsigned &RegNo, SMLoc &StartLoc, SMLoc &En
NeededWorkaround = NeededWorkaround || (Again && !(Contigious && Type));
}
std::string Collapsed = RawString;
Collapsed.erase(remove_if(Collapsed, isspace), Collapsed.end());
Collapsed.erase(llvm::remove_if(Collapsed, isspace), Collapsed.end());
StringRef FullString = Collapsed;
std::pair<StringRef, StringRef> DotSplit = FullString.split('.');
unsigned DotReg = matchRegister(DotSplit.first.lower());
@ -1273,7 +1286,7 @@ bool HexagonAsmParser::implicitExpressionLocation(OperandVector &Operands) {
}
bool HexagonAsmParser::parseExpression(MCExpr const *& Expr) {
llvm::SmallVector<AsmToken, 4> Tokens;
SmallVector<AsmToken, 4> Tokens;
MCAsmLexer &Lexer = getLexer();
bool Done = false;
static char const * Comma = ",";
@ -1452,9 +1465,8 @@ bool HexagonAsmParser::ParseInstruction(ParseInstructionInfo &Info,
return parseInstruction(Operands);
}
namespace {
MCInst makeCombineInst(int opCode, MCOperand &Rdd,
MCOperand &MO1, MCOperand &MO2) {
static MCInst makeCombineInst(int opCode, MCOperand &Rdd,
MCOperand &MO1, MCOperand &MO2) {
MCInst TmpInst;
TmpInst.setOpcode(opCode);
TmpInst.addOperand(Rdd);
@ -1463,7 +1475,6 @@ MCInst makeCombineInst(int opCode, MCOperand &Rdd,
return TmpInst;
}
}
// Define this matcher function after the auto-generated include so we
// have the match class enum definitions.
@ -1590,11 +1601,11 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
case Hexagon::A2_tfrp: {
MCOperand &MO = Inst.getOperand(1);
unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
std::string R1 = r + llvm::utostr(RegPairNum + 1);
std::string R1 = r + utostr(RegPairNum + 1);
StringRef Reg1(R1);
MO.setReg(matchRegister(Reg1));
// Add a new operand for the second register in the pair.
std::string R2 = r + llvm::utostr(RegPairNum);
std::string R2 = r + utostr(RegPairNum);
StringRef Reg2(R2);
Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Inst.setOpcode(Hexagon::A2_combinew);
@ -1605,11 +1616,11 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
case Hexagon::A2_tfrpf: {
MCOperand &MO = Inst.getOperand(2);
unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
std::string R1 = r + llvm::utostr(RegPairNum + 1);
std::string R1 = r + utostr(RegPairNum + 1);
StringRef Reg1(R1);
MO.setReg(matchRegister(Reg1));
// Add a new operand for the second register in the pair.
std::string R2 = r + llvm::utostr(RegPairNum);
std::string R2 = r + utostr(RegPairNum);
StringRef Reg2(R2);
Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrpt)
@ -1621,11 +1632,11 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
case Hexagon::A2_tfrpfnew: {
MCOperand &MO = Inst.getOperand(2);
unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
std::string R1 = r + llvm::utostr(RegPairNum + 1);
std::string R1 = r + utostr(RegPairNum + 1);
StringRef Reg1(R1);
MO.setReg(matchRegister(Reg1));
// Add a new operand for the second register in the pair.
std::string R2 = r + llvm::utostr(RegPairNum);
std::string R2 = r + utostr(RegPairNum);
StringRef Reg2(R2);
Inst.addOperand(MCOperand::createReg(matchRegister(Reg2)));
Inst.setOpcode((Inst.getOpcode() == Hexagon::A2_tfrptnew)
@ -1638,10 +1649,10 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
case Hexagon::V6_vassignp: {
MCOperand &MO = Inst.getOperand(1);
unsigned int RegPairNum = RI->getEncodingValue(MO.getReg());
std::string R1 = v + llvm::utostr(RegPairNum + 1);
std::string R1 = v + utostr(RegPairNum + 1);
MO.setReg(MatchRegisterName(R1));
// Add a new operand for the second register in the pair.
std::string R2 = v + llvm::utostr(RegPairNum);
std::string R2 = v + utostr(RegPairNum);
Inst.addOperand(MCOperand::createReg(MatchRegisterName(R2)));
Inst.setOpcode(Hexagon::V6_vcombine);
break;
@ -1711,8 +1722,8 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
getStreamer().EmitIntValue(Value, byteSize);
}
} else if (MO_1.isExpr()) {
const char *StringStart = 0;
const char *StringEnd = 0;
const char *StringStart = nullptr;
const char *StringEnd = nullptr;
if (*Operands[4]->getStartLoc().getPointer() == '#') {
StringStart = Operands[5]->getStartLoc().getPointer();
StringEnd = Operands[6]->getStartLoc().getPointer();
@ -1818,10 +1829,9 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
break;
}
case Hexagon::S2_tableidxb_goodsyntax: {
case Hexagon::S2_tableidxb_goodsyntax:
Inst.setOpcode(Hexagon::S2_tableidxb);
break;
}
case Hexagon::S2_tableidxh_goodsyntax: {
MCInst TmpInst;
@ -1880,10 +1890,9 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
break;
}
case Hexagon::M2_mpyui: {
case Hexagon::M2_mpyui:
Inst.setOpcode(Hexagon::M2_mpyi);
break;
}
case Hexagon::M2_mpysmi: {
MCInst TmpInst;
MCOperand &Rd = Inst.getOperand(0);
@ -1956,11 +1965,11 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
if (Value == 0) { // convert to $Rdd = combine ($Rs[0], $Rs[1])
MCInst TmpInst;
unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
std::string R1 = r + llvm::utostr(RegPairNum + 1);
std::string R1 = r + utostr(RegPairNum + 1);
StringRef Reg1(R1);
Rss.setReg(matchRegister(Reg1));
// Add a new operand for the second register in the pair.
std::string R2 = r + llvm::utostr(RegPairNum);
std::string R2 = r + utostr(RegPairNum);
StringRef Reg2(R2);
TmpInst.setOpcode(Hexagon::A2_combinew);
TmpInst.addOperand(Rdd);
@ -1982,14 +1991,12 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
if (RegNum & 1) { // Odd mapped to raw:hi, regpair is rodd:odd-1, like r3:2
Inst.setOpcode(Hexagon::A4_boundscheck_hi);
std::string Name =
r + llvm::utostr(RegNum) + Colon + llvm::utostr(RegNum - 1);
std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
StringRef RegPair = Name;
Rs.setReg(matchRegister(RegPair));
} else { // raw:lo
Inst.setOpcode(Hexagon::A4_boundscheck_lo);
std::string Name =
r + llvm::utostr(RegNum + 1) + Colon + llvm::utostr(RegNum);
std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
StringRef RegPair = Name;
Rs.setReg(matchRegister(RegPair));
}
@ -2001,14 +2008,12 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
unsigned int RegNum = RI->getEncodingValue(Rs.getReg());
if (RegNum & 1) { // Odd mapped to raw:hi
Inst.setOpcode(Hexagon::A2_addsph);
std::string Name =
r + llvm::utostr(RegNum) + Colon + llvm::utostr(RegNum - 1);
std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
StringRef RegPair = Name;
Rs.setReg(matchRegister(RegPair));
} else { // Even mapped raw:lo
Inst.setOpcode(Hexagon::A2_addspl);
std::string Name =
r + llvm::utostr(RegNum + 1) + Colon + llvm::utostr(RegNum);
std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
StringRef RegPair = Name;
Rs.setReg(matchRegister(RegPair));
}
@ -2020,14 +2025,12 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
if (RegNum & 1) { // Odd mapped to sat:raw:hi
Inst.setOpcode(Hexagon::M2_vrcmpys_s1_h);
std::string Name =
r + llvm::utostr(RegNum) + Colon + llvm::utostr(RegNum - 1);
std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
StringRef RegPair = Name;
Rt.setReg(matchRegister(RegPair));
} else { // Even mapped sat:raw:lo
Inst.setOpcode(Hexagon::M2_vrcmpys_s1_l);
std::string Name =
r + llvm::utostr(RegNum + 1) + Colon + llvm::utostr(RegNum);
std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
StringRef RegPair = Name;
Rt.setReg(matchRegister(RegPair));
}
@ -2042,14 +2045,12 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
if (RegNum & 1) { // Odd mapped to sat:raw:hi
TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_h);
std::string Name =
r + llvm::utostr(RegNum) + Colon + llvm::utostr(RegNum - 1);
std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
StringRef RegPair = Name;
Rt.setReg(matchRegister(RegPair));
} else { // Even mapped sat:raw:lo
TmpInst.setOpcode(Hexagon::M2_vrcmpys_acc_s1_l);
std::string Name =
r + llvm::utostr(RegNum + 1) + Colon + llvm::utostr(RegNum);
std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
StringRef RegPair = Name;
Rt.setReg(matchRegister(RegPair));
}
@ -2067,14 +2068,12 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
unsigned int RegNum = RI->getEncodingValue(Rt.getReg());
if (RegNum & 1) { // Odd mapped to rnd:sat:raw:hi
Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_h);
std::string Name =
r + llvm::utostr(RegNum) + Colon + llvm::utostr(RegNum - 1);
std::string Name = r + utostr(RegNum) + Colon + utostr(RegNum - 1);
StringRef RegPair = Name;
Rt.setReg(matchRegister(RegPair));
} else { // Even mapped rnd:sat:raw:lo
Inst.setOpcode(Hexagon::M2_vrcmpys_s1rp_l);
std::string Name =
r + llvm::utostr(RegNum + 1) + Colon + llvm::utostr(RegNum);
std::string Name = r + utostr(RegNum + 1) + Colon + utostr(RegNum);
StringRef RegPair = Name;
Rt.setReg(matchRegister(RegPair));
}
@ -2110,11 +2109,11 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
if (Value == 0) {
MCInst TmpInst;
unsigned int RegPairNum = RI->getEncodingValue(Rss.getReg());
std::string R1 = r + llvm::utostr(RegPairNum + 1);
std::string R1 = r + utostr(RegPairNum + 1);
StringRef Reg1(R1);
Rss.setReg(matchRegister(Reg1));
// Add a new operand for the second register in the pair.
std::string R2 = r + llvm::utostr(RegPairNum);
std::string R2 = r + utostr(RegPairNum);
StringRef Reg2(R2);
TmpInst.setOpcode(Hexagon::A2_combinew);
TmpInst.addOperand(Rdd);
@ -2148,7 +2147,6 @@ int HexagonAsmParser::processInstruction(MCInst &Inst,
return Match_Success;
}
unsigned HexagonAsmParser::matchRegister(StringRef Name) {
if (unsigned Reg = MatchRegisterName(Name))
return Reg;

View File

@ -14,21 +14,23 @@
#include "MCTargetDesc/HexagonMCChecker.h"
#include "MCTargetDesc/HexagonMCTargetDesc.h"
#include "MCTargetDesc/HexagonMCInstrInfo.h"
#include "MCTargetDesc/HexagonInstPrinter.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/MC/MCDisassembler/MCDisassembler.h"
#include "llvm/MC/MCContext.h"
#include "llvm/MC/MCExpr.h"
#include "llvm/MC/MCFixedLenDisassembler.h"
#include "llvm/MC/MCInst.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrInfo.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/MC/MCSubtargetInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LEB128.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Support/TargetRegistry.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <memory>
using namespace llvm;
using namespace Hexagon;
@ -36,11 +38,13 @@ using namespace Hexagon;
typedef MCDisassembler::DecodeStatus DecodeStatus;
namespace {
/// \brief Hexagon disassembler for all Hexagon platforms.
class HexagonDisassembler : public MCDisassembler {
public:
std::unique_ptr<MCInstrInfo const> const MCII;
std::unique_ptr<MCInst *> CurrentBundle;
HexagonDisassembler(const MCSubtargetInfo &STI, MCContext &Ctx,
MCInstrInfo const *MCII)
: MCDisassembler(STI, Ctx), MCII(MCII), CurrentBundle(new MCInst *) {}
@ -57,7 +61,8 @@ public:
void adjustExtendedInstructions(MCInst &MCI, MCInst const &MCB) const;
void addSubinstOperands(MCInst *MI, unsigned opcode, unsigned inst) const;
};
}
} // end anonymous namespace
// Forward declare these because the auto-generated code will reference them.
// Definitions are further down.
@ -161,7 +166,7 @@ DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
*CurrentBundle = &MI;
MI = HexagonMCInstrInfo::createBundle();
while (Result == Success && Complete == false) {
while (Result == Success && !Complete) {
if (Bytes.size() < HEXAGON_INSTR_SIZE)
return MCDisassembler::Fail;
MCInst *Inst = new (getContext()) MCInst;
@ -178,14 +183,13 @@ DecodeStatus HexagonDisassembler::getInstruction(MCInst &MI, uint64_t &Size,
return MCDisassembler::Success;
}
namespace {
HexagonDisassembler const &disassembler(void const *Decoder) {
static HexagonDisassembler const &disassembler(void const *Decoder) {
return *static_cast<HexagonDisassembler const *>(Decoder);
}
MCContext &contextFromDecoder(void const *Decoder) {
static MCContext &contextFromDecoder(void const *Decoder) {
return disassembler(Decoder).getContext();
}
}
DecodeStatus HexagonDisassembler::getSingleInstruction(
MCInst &MI, MCInst &MCB, ArrayRef<uint8_t> Bytes, uint64_t Address,
@ -328,8 +332,7 @@ DecodeStatus HexagonDisassembler::getSingleInstruction(
// follow the duplex model, so the register values in the MCInst are
// incorrect. If the instruction is a compound, loop through the
// operands and change registers appropriately.
if (llvm::HexagonMCInstrInfo::getType(*MCII, MI) ==
HexagonII::TypeCOMPOUND) {
if (HexagonMCInstrInfo::getType(*MCII, MI) == HexagonII::TypeCOMPOUND) {
for (MCInst::iterator i = MI.begin(), last = MI.end(); i < last; ++i) {
if (i->isReg()) {
unsigned reg = i->getReg() - Hexagon::R0;
@ -496,10 +499,6 @@ void HexagonDisassembler::adjustExtendedInstructions(MCInst &MCI,
}
}
namespace llvm {
extern const MCInstrDesc HexagonInsts[];
}
static DecodeStatus DecodeRegisterClass(MCInst &Inst, unsigned RegNo,
ArrayRef<MCPhysReg> Table) {
if (RegNo < Table.size()) {
@ -651,11 +650,8 @@ static DecodeStatus DecodeModRegsRegisterClass(MCInst &Inst, unsigned RegNo,
return MCDisassembler::Success;
}
namespace {
uint32_t fullValue(MCInstrInfo const &MCII,
MCInst &MCB,
MCInst &MI,
int64_t Value) {
static uint32_t fullValue(MCInstrInfo const &MCII, MCInst &MCB, MCInst &MI,
int64_t Value) {
MCInst const *Extender = HexagonMCInstrInfo::extenderForIndex(
MCB, HexagonMCInstrInfo::bundleSize(MCB));
if(!Extender || MI.size() != HexagonMCInstrInfo::getExtendableOp(MCII, MI))
@ -669,8 +665,9 @@ uint32_t fullValue(MCInstrInfo const &MCII,
uint32_t Operand = Upper26 | Lower6;
return Operand;
}
template <size_t T>
void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) {
static void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) {
HexagonDisassembler const &Disassembler = disassembler(Decoder);
int64_t FullValue = fullValue(*Disassembler.MCII,
**Disassembler.CurrentBundle,
@ -679,7 +676,6 @@ void signedDecoder(MCInst &MI, unsigned tmp, const void *Decoder) {
HexagonMCInstrInfo::addConstant(MI, Extended,
Disassembler.getContext());
}
}
static DecodeStatus unsignedImmDecoder(MCInst &MI, unsigned tmp,
uint64_t /*Address*/,
@ -859,7 +855,6 @@ static const size_t NumCondS = array_lengthof(StoreConditionalOpcodeData);
static const size_t NumLS = array_lengthof(LoadStoreOpcodeData);
static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
unsigned MachineOpcode = 0;
unsigned LLVMOpcode = 0;
@ -898,19 +893,18 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
case Hexagon::S4_pstorerdf_abs:
case Hexagon::S4_pstorerdt_abs:
case Hexagon::S4_pstorerdfnew_abs:
case Hexagon::S4_pstorerdtnew_abs: {
case Hexagon::S4_pstorerdtnew_abs:
// op: Pv
Value = insn & UINT64_C(3);
DecodePredRegsRegisterClass(MI, Value, 0, 0);
DecodePredRegsRegisterClass(MI, Value, 0, nullptr);
// op: u6
Value = (insn >> 12) & UINT64_C(48);
Value |= (insn >> 3) & UINT64_C(15);
MI.addOperand(MCOperand::createImm(Value));
// op: Rtt
Value = (insn >> 8) & UINT64_C(31);
DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
DecodeDoubleRegsRegisterClass(MI, Value, 0, nullptr);
break;
}
case Hexagon::S4_pstorerbnewf_abs:
case Hexagon::S4_pstorerbnewt_abs:
@ -923,19 +917,18 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
case Hexagon::S4_pstorerinewf_abs:
case Hexagon::S4_pstorerinewt_abs:
case Hexagon::S4_pstorerinewfnew_abs:
case Hexagon::S4_pstorerinewtnew_abs: {
case Hexagon::S4_pstorerinewtnew_abs:
// op: Pv
Value = insn & UINT64_C(3);
DecodePredRegsRegisterClass(MI, Value, 0, 0);
DecodePredRegsRegisterClass(MI, Value, 0, nullptr);
// op: u6
Value = (insn >> 12) & UINT64_C(48);
Value |= (insn >> 3) & UINT64_C(15);
MI.addOperand(MCOperand::createImm(Value));
// op: Nt
Value = (insn >> 8) & UINT64_C(7);
DecodeIntRegsRegisterClass(MI, Value, 0, 0);
DecodeIntRegsRegisterClass(MI, Value, 0, nullptr);
break;
}
case Hexagon::S4_pstorerbf_abs:
case Hexagon::S4_pstorerbt_abs:
@ -948,36 +941,34 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
case Hexagon::S4_pstorerif_abs:
case Hexagon::S4_pstorerit_abs:
case Hexagon::S4_pstorerifnew_abs:
case Hexagon::S4_pstoreritnew_abs: {
case Hexagon::S4_pstoreritnew_abs:
// op: Pv
Value = insn & UINT64_C(3);
DecodePredRegsRegisterClass(MI, Value, 0, 0);
DecodePredRegsRegisterClass(MI, Value, 0, nullptr);
// op: u6
Value = (insn >> 12) & UINT64_C(48);
Value |= (insn >> 3) & UINT64_C(15);
MI.addOperand(MCOperand::createImm(Value));
// op: Rt
Value = (insn >> 8) & UINT64_C(31);
DecodeIntRegsRegisterClass(MI, Value, 0, 0);
DecodeIntRegsRegisterClass(MI, Value, 0, nullptr);
break;
}
case Hexagon::L4_ploadrdf_abs:
case Hexagon::L4_ploadrdt_abs:
case Hexagon::L4_ploadrdfnew_abs:
case Hexagon::L4_ploadrdtnew_abs: {
case Hexagon::L4_ploadrdtnew_abs:
// op: Rdd
Value = insn & UINT64_C(31);
DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
DecodeDoubleRegsRegisterClass(MI, Value, 0, nullptr);
// op: Pt
Value = ((insn >> 9) & UINT64_C(3));
DecodePredRegsRegisterClass(MI, Value, 0, 0);
DecodePredRegsRegisterClass(MI, Value, 0, nullptr);
// op: u6
Value = ((insn >> 15) & UINT64_C(62));
Value |= ((insn >> 8) & UINT64_C(1));
MI.addOperand(MCOperand::createImm(Value));
break;
}
case Hexagon::L4_ploadrbf_abs:
case Hexagon::L4_ploadrbt_abs:
@ -1001,10 +992,10 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
case Hexagon::L4_ploadritnew_abs:
// op: Rd
Value = insn & UINT64_C(31);
DecodeIntRegsRegisterClass(MI, Value, 0, 0);
DecodeIntRegsRegisterClass(MI, Value, 0, nullptr);
// op: Pt
Value = (insn >> 9) & UINT64_C(3);
DecodePredRegsRegisterClass(MI, Value, 0, 0);
DecodePredRegsRegisterClass(MI, Value, 0, nullptr);
// op: u6
Value = (insn >> 15) & UINT64_C(62);
Value |= (insn >> 8) & UINT64_C(1);
@ -1020,28 +1011,26 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
++shift;
// op: g16_0
case Hexagon::PS_loadrbabs:
case Hexagon::PS_loadrubabs: {
case Hexagon::PS_loadrubabs:
// op: Rd
Value |= insn & UINT64_C(31);
DecodeIntRegsRegisterClass(MI, Value, 0, 0);
DecodeIntRegsRegisterClass(MI, Value, 0, nullptr);
Value = (insn >> 11) & UINT64_C(49152);
Value |= (insn >> 7) & UINT64_C(15872);
Value |= (insn >> 5) & UINT64_C(511);
MI.addOperand(MCOperand::createImm(Value << shift));
break;
}
case Hexagon::PS_loadrdabs: {
case Hexagon::PS_loadrdabs:
Value = insn & UINT64_C(31);
DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
DecodeDoubleRegsRegisterClass(MI, Value, 0, nullptr);
Value = (insn >> 11) & UINT64_C(49152);
Value |= (insn >> 7) & UINT64_C(15872);
Value |= (insn >> 5) & UINT64_C(511);
MI.addOperand(MCOperand::createImm(Value << 3));
break;
}
case Hexagon::PS_storerdabs: {
case Hexagon::PS_storerdabs:
// op: g16_3
Value = (insn >> 11) & UINT64_C(49152);
Value |= (insn >> 7) & UINT64_C(15872);
@ -1050,9 +1039,8 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
MI.addOperand(MCOperand::createImm(Value << 3));
// op: Rtt
Value = (insn >> 8) & UINT64_C(31);
DecodeDoubleRegsRegisterClass(MI, Value, 0, 0);
DecodeDoubleRegsRegisterClass(MI, Value, 0, nullptr);
break;
}
// op: g16_2
case Hexagon::PS_storerinewabs:
@ -1061,7 +1049,7 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
case Hexagon::PS_storerhnewabs:
++shift;
// op: g16_0
case Hexagon::PS_storerbnewabs: {
case Hexagon::PS_storerbnewabs:
Value = (insn >> 11) & UINT64_C(49152);
Value |= (insn >> 7) & UINT64_C(15872);
Value |= (insn >> 5) & UINT64_C(256);
@ -1069,9 +1057,8 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
MI.addOperand(MCOperand::createImm(Value << shift));
// op: Nt
Value = (insn >> 8) & UINT64_C(7);
DecodeIntRegsRegisterClass(MI, Value, 0, 0);
DecodeIntRegsRegisterClass(MI, Value, 0, nullptr);
break;
}
// op: g16_2
case Hexagon::PS_storeriabs:
@ -1081,7 +1068,7 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
case Hexagon::PS_storerfabs:
++shift;
// op: g16_0
case Hexagon::PS_storerbabs: {
case Hexagon::PS_storerbabs:
Value = (insn >> 11) & UINT64_C(49152);
Value |= (insn >> 7) & UINT64_C(15872);
Value |= (insn >> 5) & UINT64_C(256);
@ -1089,10 +1076,9 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
MI.addOperand(MCOperand::createImm(Value << shift));
// op: Rt
Value = (insn >> 8) & UINT64_C(31);
DecodeIntRegsRegisterClass(MI, Value, 0, 0);
DecodeIntRegsRegisterClass(MI, Value, 0, nullptr);
break;
}
}
return MCDisassembler::Success;
}
return MCDisassembler::Fail;
@ -1100,7 +1086,6 @@ static DecodeStatus decodeSpecial(MCInst &MI, uint32_t insn) {
static DecodeStatus decodeImmext(MCInst &MI, uint32_t insn,
void const *Decoder) {
// Instruction Class for a constant a extender: bits 31:28 = 0x0000
if ((~insn & 0xf0000000) == 0xf0000000) {
unsigned Value;

View File

@ -11,16 +11,36 @@
#include "HexagonBitTracker.h"
#include "HexagonTargetMachine.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <algorithm>
#include <cassert>
#include <cstdint>
#include <iterator>
#include <limits>
#include <utility>
#include <vector>
using namespace llvm;
@ -28,16 +48,19 @@ static cl::opt<bool> PreserveTiedOps("hexbit-keep-tied", cl::Hidden,
cl::init(true), cl::desc("Preserve subregisters in tied operands"));
namespace llvm {
void initializeHexagonBitSimplifyPass(PassRegistry& Registry);
FunctionPass *createHexagonBitSimplify();
}
} // end namespace llvm
namespace {
// Set of virtual registers, based on BitVector.
struct RegisterSet : private BitVector {
RegisterSet() : BitVector() {}
RegisterSet() = default;
explicit RegisterSet(unsigned s, bool t = false) : BitVector(s, t) {}
RegisterSet(const RegisterSet &RS) : BitVector(RS) {}
RegisterSet(const RegisterSet &RS) = default;
using BitVector::clear;
using BitVector::count;
@ -108,20 +131,23 @@ namespace {
if (size() <= Idx)
resize(std::max(Idx+1, 32U));
}
static inline unsigned v2x(unsigned v) {
return TargetRegisterInfo::virtReg2Index(v);
}
static inline unsigned x2v(unsigned x) {
return TargetRegisterInfo::index2VirtReg(x);
}
};
struct PrintRegSet {
PrintRegSet(const RegisterSet &S, const TargetRegisterInfo *RI)
: RS(S), TRI(RI) {}
friend raw_ostream &operator<< (raw_ostream &OS,
const PrintRegSet &P);
private:
const RegisterSet &RS;
const TargetRegisterInfo *TRI;
@ -136,27 +162,28 @@ namespace {
OS << " }";
return OS;
}
}
namespace {
class Transformation;
class HexagonBitSimplify : public MachineFunctionPass {
public:
static char ID;
HexagonBitSimplify() : MachineFunctionPass(ID), MDT(0) {
HexagonBitSimplify() : MachineFunctionPass(ID), MDT(nullptr) {
initializeHexagonBitSimplifyPass(*PassRegistry::getPassRegistry());
}
virtual StringRef getPassName() const {
StringRef getPassName() const override {
return "Hexagon bit simplification";
}
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<MachineDominatorTree>();
AU.addPreserved<MachineDominatorTree>();
MachineFunctionPass::getAnalysisUsage(AU);
}
virtual bool runOnMachineFunction(MachineFunction &MF);
bool runOnMachineFunction(MachineFunction &MF) override;
static void getInstrDefs(const MachineInstr &MI, RegisterSet &Defs);
static void getInstrUses(const MachineInstr &MI, RegisterSet &Uses);
@ -199,18 +226,20 @@ namespace {
char HexagonBitSimplify::ID = 0;
typedef HexagonBitSimplify HBS;
// The purpose of this class is to provide a common facility to traverse
// the function top-down or bottom-up via the dominator tree, and keep
// track of the available registers.
class Transformation {
public:
bool TopDown;
Transformation(bool TD) : TopDown(TD) {}
virtual ~Transformation() = default;
virtual bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) = 0;
virtual ~Transformation() {}
};
}
} // end anonymous namespace
INITIALIZE_PASS_BEGIN(HexagonBitSimplify, "hexbit",
"Hexagon bit simplification", false, false)
@ -218,7 +247,6 @@ INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
INITIALIZE_PASS_END(HexagonBitSimplify, "hexbit",
"Hexagon bit simplification", false, false)
bool HexagonBitSimplify::visitBlock(MachineBasicBlock &B, Transformation &T,
RegisterSet &AVs) {
MachineDomTreeNode *N = MDT->getNode(&B);
@ -297,7 +325,6 @@ bool HexagonBitSimplify::isZero(const BitTracker::RegisterCell &RC,
return true;
}
bool HexagonBitSimplify::getConst(const BitTracker::RegisterCell &RC,
uint16_t B, uint16_t W, uint64_t &U) {
assert(B < RC.width() && B+W <= RC.width());
@ -314,7 +341,6 @@ bool HexagonBitSimplify::getConst(const BitTracker::RegisterCell &RC,
return true;
}
bool HexagonBitSimplify::replaceReg(unsigned OldR, unsigned NewR,
MachineRegisterInfo &MRI) {
if (!TargetRegisterInfo::isVirtualRegister(OldR) ||
@ -329,7 +355,6 @@ bool HexagonBitSimplify::replaceReg(unsigned OldR, unsigned NewR,
return Begin != End;
}
bool HexagonBitSimplify::replaceRegWithSub(unsigned OldR, unsigned NewR,
unsigned NewSR, MachineRegisterInfo &MRI) {
if (!TargetRegisterInfo::isVirtualRegister(OldR) ||
@ -347,7 +372,6 @@ bool HexagonBitSimplify::replaceRegWithSub(unsigned OldR, unsigned NewR,
return Begin != End;
}
bool HexagonBitSimplify::replaceSubWithSub(unsigned OldR, unsigned OldSR,
unsigned NewR, unsigned NewSR, MachineRegisterInfo &MRI) {
if (!TargetRegisterInfo::isVirtualRegister(OldR) ||
@ -367,7 +391,6 @@ bool HexagonBitSimplify::replaceSubWithSub(unsigned OldR, unsigned OldSR,
return Begin != End;
}
// For a register ref (pair Reg:Sub), set Begin to the position of the LSB
// of Sub in Reg, and set Width to the size of Sub in bits. Return true,
// if this succeeded, otherwise return false.
@ -423,7 +446,6 @@ bool HexagonBitSimplify::parseRegSequence(const MachineInstr &I,
return false;
}
// All stores (except 64-bit stores) take a 32-bit register as the source
// of the value to be stored. If the instruction stores into a location
// that is shorter than 32 bits, some bits of the source register are not
@ -581,7 +603,6 @@ bool HexagonBitSimplify::getUsedBitsInStore(unsigned Opc, BitVector &Bits,
return false;
}
// For an instruction with opcode Opc, calculate the set of bits that it
// uses in a register in operand OpN. This only calculates the set of used
// bits for cases where it does not depend on any operands (as is the case
@ -861,7 +882,6 @@ bool HexagonBitSimplify::getUsedBits(unsigned Opc, unsigned OpN,
return false;
}
// Calculate the register class that matches Reg:Sub. For example, if
// vreg1 is a double register, then vreg1:isub_hi would match the "int"
// register class.
@ -894,7 +914,6 @@ const TargetRegisterClass *HexagonBitSimplify::getFinalVRegClass(
return nullptr;
}
// Check if RD could be replaced with RS at any possible use of RD.
// For example a predicate register cannot be replaced with a integer
// register, but a 64-bit register with a subregister can be replaced
@ -912,21 +931,18 @@ bool HexagonBitSimplify::isTransparentCopy(const BitTracker::RegisterRef &RD,
return DRC == getFinalVRegClass(RS, MRI);
}
bool HexagonBitSimplify::hasTiedUse(unsigned Reg, MachineRegisterInfo &MRI,
unsigned NewSub) {
if (!PreserveTiedOps)
return false;
return any_of(MRI.use_operands(Reg),
[NewSub] (const MachineOperand &Op) -> bool {
return Op.getSubReg() != NewSub && Op.isTied();
});
return llvm::any_of(MRI.use_operands(Reg),
[NewSub] (const MachineOperand &Op) -> bool {
return Op.getSubReg() != NewSub && Op.isTied();
});
}
//
// Dead code elimination
//
namespace {
class DeadCodeElimination {
public:
DeadCodeElimination(MachineFunction &mf, MachineDominatorTree &mdt)
@ -946,8 +962,8 @@ namespace {
MachineDominatorTree &MDT;
MachineRegisterInfo &MRI;
};
}
} // end anonymous namespace
bool DeadCodeElimination::isDead(unsigned R) const {
for (auto I = MRI.use_begin(R), E = MRI.use_end(); I != E; ++I) {
@ -965,7 +981,6 @@ bool DeadCodeElimination::isDead(unsigned R) const {
return true;
}
bool DeadCodeElimination::runOnNode(MachineDomTreeNode *N) {
bool Changed = false;
typedef GraphTraits<MachineDomTreeNode*> GTN;
@ -1015,8 +1030,8 @@ bool DeadCodeElimination::runOnNode(MachineDomTreeNode *N) {
return Changed;
}
namespace {
//
// Eliminate redundant instructions
//
// This transformation will identify instructions where the output register
@ -1027,13 +1042,14 @@ bool DeadCodeElimination::runOnNode(MachineDomTreeNode *N) {
// registers.
// If the output matches an input, the instruction is replaced with COPY.
// The copies will be removed by another transformation.
namespace {
class RedundantInstrElimination : public Transformation {
public:
RedundantInstrElimination(BitTracker &bt, const HexagonInstrInfo &hii,
MachineRegisterInfo &mri)
: Transformation(true), HII(hii), MRI(mri), BT(bt) {}
bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
private:
bool isLossyShiftLeft(const MachineInstr &MI, unsigned OpN,
unsigned &LostB, unsigned &LostE);
@ -1048,8 +1064,8 @@ namespace {
MachineRegisterInfo &MRI;
BitTracker &BT;
};
}
} // end anonymous namespace
// Check if the instruction is a lossy shift left, where the input being
// shifted is the operand OpN of MI. If true, [LostB, LostE) is the range
@ -1057,6 +1073,7 @@ namespace {
bool RedundantInstrElimination::isLossyShiftLeft(const MachineInstr &MI,
unsigned OpN, unsigned &LostB, unsigned &LostE) {
using namespace Hexagon;
unsigned Opc = MI.getOpcode();
unsigned ImN, RegN, Width;
switch (Opc) {
@ -1110,13 +1127,13 @@ bool RedundantInstrElimination::isLossyShiftLeft(const MachineInstr &MI,
return true;
}
// Check if the instruction is a lossy shift right, where the input being
// shifted is the operand OpN of MI. If true, [LostB, LostE) is the range
// of bit indices that are lost.
bool RedundantInstrElimination::isLossyShiftRight(const MachineInstr &MI,
unsigned OpN, unsigned &LostB, unsigned &LostE) {
using namespace Hexagon;
unsigned Opc = MI.getOpcode();
unsigned ImN, RegN;
switch (Opc) {
@ -1173,7 +1190,6 @@ bool RedundantInstrElimination::isLossyShiftRight(const MachineInstr &MI,
return true;
}
// Calculate the bit vector that corresponds to the used bits of register Reg.
// The vector Bits has the same size, as the size of Reg in bits. If the cal-
// culation fails (i.e. the used bits are unknown), it returns false. Other-
@ -1210,7 +1226,6 @@ bool RedundantInstrElimination::computeUsedBits(unsigned Reg, BitVector &Bits) {
return true;
}
// Calculate the bits used by instruction MI in a register in operand OpN.
// Return true/false if the calculation succeeds/fails. If is succeeds, set
// used bits in Bits. This function does not reset any bits in Bits, so
@ -1251,7 +1266,6 @@ bool RedundantInstrElimination::computeUsedBits(const MachineInstr &MI,
return GotBits;
}
// Calculates the used bits in RD ("defined register"), and checks if these
// bits in RS ("used register") and RD are identical.
bool RedundantInstrElimination::usedBitsEqual(BitTracker::RegisterRef RD,
@ -1278,7 +1292,6 @@ bool RedundantInstrElimination::usedBitsEqual(BitTracker::RegisterRef RD,
return true;
}
bool RedundantInstrElimination::processBlock(MachineBasicBlock &B,
const RegisterSet&) {
if (!BT.reached(&B))
@ -1348,20 +1361,19 @@ bool RedundantInstrElimination::processBlock(MachineBasicBlock &B,
return Changed;
}
namespace {
//
// Const generation
//
// Recognize instructions that produce constant values known at compile-time.
// Replace them with register definitions that load these constants directly.
namespace {
class ConstGeneration : public Transformation {
public:
ConstGeneration(BitTracker &bt, const HexagonInstrInfo &hii,
MachineRegisterInfo &mri)
: Transformation(true), HII(hii), MRI(mri), BT(bt) {}
bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
static bool isTfrConst(const MachineInstr &MI);
private:
unsigned genTfrConst(const TargetRegisterClass *RC, int64_t C,
MachineBasicBlock &B, MachineBasicBlock::iterator At, DebugLoc &DL);
@ -1370,7 +1382,8 @@ namespace {
MachineRegisterInfo &MRI;
BitTracker &BT;
};
}
} // end anonymous namespace
bool ConstGeneration::isTfrConst(const MachineInstr &MI) {
unsigned Opc = MI.getOpcode();
@ -1388,7 +1401,6 @@ bool ConstGeneration::isTfrConst(const MachineInstr &MI) {
return false;
}
// Generate a transfer-immediate instruction that is appropriate for the
// register class and the actual value being transferred.
unsigned ConstGeneration::genTfrConst(const TargetRegisterClass *RC, int64_t C,
@ -1437,7 +1449,6 @@ unsigned ConstGeneration::genTfrConst(const TargetRegisterClass *RC, int64_t C,
return 0;
}
bool ConstGeneration::processBlock(MachineBasicBlock &B, const RegisterSet&) {
if (!BT.reached(&B))
return false;
@ -1471,25 +1482,19 @@ bool ConstGeneration::processBlock(MachineBasicBlock &B, const RegisterSet&) {
return Changed;
}
namespace {
//
// Copy generation
//
// Identify pairs of available registers which hold identical values.
// In such cases, only one of them needs to be calculated, the other one
// will be defined as a copy of the first.
//
// Copy propagation
//
// Eliminate register copies RD = RS, by replacing the uses of RD with
// with uses of RS.
namespace {
class CopyGeneration : public Transformation {
public:
CopyGeneration(BitTracker &bt, const HexagonInstrInfo &hii,
const HexagonRegisterInfo &hri, MachineRegisterInfo &mri)
: Transformation(true), HII(hii), HRI(hri), MRI(mri), BT(bt) {}
bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
private:
bool findMatch(const BitTracker::RegisterRef &Inp,
BitTracker::RegisterRef &Out, const RegisterSet &AVs);
@ -1501,12 +1506,17 @@ namespace {
RegisterSet Forbidden;
};
// Eliminate register copies RD = RS, by replacing the uses of RD with
// with uses of RS.
class CopyPropagation : public Transformation {
public:
CopyPropagation(const HexagonRegisterInfo &hri, MachineRegisterInfo &mri)
: Transformation(false), HRI(hri), MRI(mri) {}
bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
static bool isCopyReg(unsigned Opc, bool NoConv);
private:
bool propagateRegCopy(MachineInstr &MI);
@ -1514,8 +1524,7 @@ namespace {
MachineRegisterInfo &MRI;
};
}
} // end anonymous namespace
/// Check if there is a register in AVs that is identical to Inp. If so,
/// set Out to the found register. The output may be a pair Reg:Sub.
@ -1566,7 +1575,6 @@ bool CopyGeneration::findMatch(const BitTracker::RegisterRef &Inp,
return false;
}
bool CopyGeneration::processBlock(MachineBasicBlock &B,
const RegisterSet &AVs) {
if (!BT.reached(&B))
@ -1631,7 +1639,6 @@ bool CopyGeneration::processBlock(MachineBasicBlock &B,
return Changed;
}
bool CopyPropagation::isCopyReg(unsigned Opc, bool NoConv) {
switch (Opc) {
case TargetOpcode::COPY:
@ -1651,7 +1658,6 @@ bool CopyPropagation::isCopyReg(unsigned Opc, bool NoConv) {
return false;
}
bool CopyPropagation::propagateRegCopy(MachineInstr &MI) {
bool Changed = false;
unsigned Opc = MI.getOpcode();
@ -1706,7 +1712,6 @@ bool CopyPropagation::propagateRegCopy(MachineInstr &MI) {
return Changed;
}
bool CopyPropagation::processBlock(MachineBasicBlock &B, const RegisterSet&) {
std::vector<MachineInstr*> Instrs;
for (auto I = B.rbegin(), E = B.rend(); I != E; ++I)
@ -1723,21 +1728,20 @@ bool CopyPropagation::processBlock(MachineBasicBlock &B, const RegisterSet&) {
return Changed;
}
namespace {
//
// Bit simplification
//
// Recognize patterns that can be simplified and replace them with the
// simpler forms.
// This is by no means complete
namespace {
class BitSimplification : public Transformation {
public:
BitSimplification(BitTracker &bt, const HexagonInstrInfo &hii,
const HexagonRegisterInfo &hri, MachineRegisterInfo &mri,
MachineFunction &mf)
: Transformation(true), HII(hii), HRI(hri), MRI(mri), MF(mf), BT(bt) {}
bool processBlock(MachineBasicBlock &B, const RegisterSet &AVs) override;
private:
struct RegHalf : public BitTracker::RegisterRef {
bool Low; // Low/High halfword.
@ -1770,8 +1774,8 @@ namespace {
MachineFunction &MF;
BitTracker &BT;
};
}
} // end anonymous namespace
// Check if the bits [B..B+16) in register cell RC form a valid halfword,
// i.e. [0..16), [16..32), etc. of some register. If so, return true and
@ -1854,7 +1858,6 @@ bool BitSimplification::matchHalf(unsigned SelfR,
return true;
}
bool BitSimplification::validateReg(BitTracker::RegisterRef R, unsigned Opc,
unsigned OpNum) {
auto *OpRC = HII.getRegClass(HII.get(Opc), OpNum, &HRI, MF);
@ -1862,7 +1865,6 @@ bool BitSimplification::validateReg(BitTracker::RegisterRef R, unsigned Opc,
return OpRC->hasSubClassEq(RRC);
}
// Check if RC matches the pattern of a S2_packhl. If so, return true and
// set the inputs Rs and Rt.
bool BitSimplification::matchPackhl(unsigned SelfR,
@ -1886,7 +1888,6 @@ bool BitSimplification::matchPackhl(unsigned SelfR,
return true;
}
unsigned BitSimplification::getCombineOpcode(bool HLow, bool LLow) {
return HLow ? LLow ? Hexagon::A2_combine_ll
: Hexagon::A2_combine_lh
@ -1894,7 +1895,6 @@ unsigned BitSimplification::getCombineOpcode(bool HLow, bool LLow) {
: Hexagon::A2_combine_hh;
}
// If MI stores the upper halfword of a register (potentially obtained via
// shifts or extracts), replace it with a storerf instruction. This could
// cause the "extraction" code to become dead.
@ -1919,7 +1919,6 @@ bool BitSimplification::genStoreUpperHalf(MachineInstr *MI) {
return true;
}
// If MI stores a value known at compile-time, and the value is within a range
// that avoids using constant-extenders, replace it with a store-immediate.
bool BitSimplification::genStoreImmediate(MachineInstr *MI) {
@ -1988,7 +1987,6 @@ bool BitSimplification::genStoreImmediate(MachineInstr *MI) {
return true;
}
// If MI is equivalent o S2_packhl, generate the S2_packhl. MI could be the
// last instruction in a sequence that results in something equivalent to
// the pack-halfwords. The intent is to cause the entire sequence to become
@ -2018,7 +2016,6 @@ bool BitSimplification::genPackhl(MachineInstr *MI,
return true;
}
// If MI produces halfword of the input in the low half of the output,
// replace it with zero-extend or extractu.
bool BitSimplification::genExtractHalf(MachineInstr *MI,
@ -2058,7 +2055,6 @@ bool BitSimplification::genExtractHalf(MachineInstr *MI,
return true;
}
// If MI is equivalent to a combine(.L/.H, .L/.H) replace with with the
// combine.
bool BitSimplification::genCombineHalf(MachineInstr *MI,
@ -2091,7 +2087,6 @@ bool BitSimplification::genCombineHalf(MachineInstr *MI,
return true;
}
// If MI resets high bits of a register and keeps the lower ones, replace it
// with zero-extend byte/half, and-immediate, or extractu, as appropriate.
bool BitSimplification::genExtractLow(MachineInstr *MI,
@ -2154,7 +2149,6 @@ bool BitSimplification::genExtractLow(MachineInstr *MI,
return false;
}
// Check for tstbit simplification opportunity, where the bit being checked
// can be tracked back to another register. For example:
// vreg2 = S2_lsr_i_r vreg1, 5
@ -2184,7 +2178,7 @@ bool BitSimplification::simplifyTstbit(MachineInstr *MI,
// Need to map V.RefI.Reg to a 32-bit register, i.e. if it is
// a double register, need to use a subregister and adjust bit
// number.
unsigned P = UINT_MAX;
unsigned P = std::numeric_limits<unsigned>::max();
BitTracker::RegisterRef RR(V.RefI.Reg, 0);
if (TC == &Hexagon::DoubleRegsRegClass) {
P = V.RefI.Pos;
@ -2196,7 +2190,7 @@ bool BitSimplification::simplifyTstbit(MachineInstr *MI,
} else if (TC == &Hexagon::IntRegsRegClass) {
P = V.RefI.Pos;
}
if (P != UINT_MAX) {
if (P != std::numeric_limits<unsigned>::max()) {
unsigned NewR = MRI.createVirtualRegister(&Hexagon::PredRegsRegClass);
BuildMI(B, At, DL, HII.get(Hexagon::S2_tstbit_i), NewR)
.addReg(RR.Reg, 0, RR.Sub)
@ -2216,7 +2210,6 @@ bool BitSimplification::simplifyTstbit(MachineInstr *MI,
return false;
}
bool BitSimplification::processBlock(MachineBasicBlock &B,
const RegisterSet &AVs) {
if (!BT.reached(&B))
@ -2275,7 +2268,6 @@ bool BitSimplification::processBlock(MachineBasicBlock &B,
return Changed;
}
bool HexagonBitSimplify::runOnMachineFunction(MachineFunction &MF) {
if (skipFunction(*MF.getFunction()))
return false;
@ -2335,7 +2327,6 @@ bool HexagonBitSimplify::runOnMachineFunction(MachineFunction &MF) {
return Changed;
}
// Recognize loops where the code at the end of the loop matches the code
// before the entry of the loop, and the matching code is such that is can
// be simplified. This pass relies on the bit simplification above and only
@ -2399,16 +2390,20 @@ bool HexagonBitSimplify::runOnMachineFunction(MachineFunction &MF) {
// }:endloop0
namespace llvm {
FunctionPass *createHexagonLoopRescheduling();
void initializeHexagonLoopReschedulingPass(PassRegistry&);
}
} // end namespace llvm
namespace {
class HexagonLoopRescheduling : public MachineFunctionPass {
public:
static char ID;
HexagonLoopRescheduling() : MachineFunctionPass(ID),
HII(0), HRI(0), MRI(0), BTP(0) {
HII(nullptr), HRI(nullptr), MRI(nullptr), BTP(nullptr) {
initializeHexagonLoopReschedulingPass(*PassRegistry::getPassRegistry());
}
@ -2448,14 +2443,14 @@ namespace {
MachineBasicBlock::iterator At, unsigned OldPhiR, unsigned NewPredR);
bool processLoop(LoopCand &C);
};
}
} // end anonymous namespace
char HexagonLoopRescheduling::ID = 0;
INITIALIZE_PASS(HexagonLoopRescheduling, "hexagon-loop-resched",
"Hexagon Loop Rescheduling", false, false)
HexagonLoopRescheduling::PhiInfo::PhiInfo(MachineInstr &P,
MachineBasicBlock &B) {
DefR = HexagonLoopRescheduling::getDefReg(&P);
@ -2472,7 +2467,6 @@ HexagonLoopRescheduling::PhiInfo::PhiInfo(MachineInstr &P,
}
}
unsigned HexagonLoopRescheduling::getDefReg(const MachineInstr *MI) {
RegisterSet Defs;
HBS::getInstrDefs(*MI, Defs);
@ -2481,7 +2475,6 @@ unsigned HexagonLoopRescheduling::getDefReg(const MachineInstr *MI) {
return Defs.find_first();
}
bool HexagonLoopRescheduling::isConst(unsigned Reg) const {
if (!BTP->has(Reg))
return false;
@ -2494,7 +2487,6 @@ bool HexagonLoopRescheduling::isConst(unsigned Reg) const {
return true;
}
bool HexagonLoopRescheduling::isBitShuffle(const MachineInstr *MI,
unsigned DefR) const {
unsigned Opc = MI->getOpcode();
@ -2525,7 +2517,6 @@ bool HexagonLoopRescheduling::isBitShuffle(const MachineInstr *MI,
return false;
}
bool HexagonLoopRescheduling::isStoreInput(const MachineInstr *MI,
unsigned InpR) const {
for (unsigned i = 0, n = MI->getNumOperands(); i < n; ++i) {
@ -2538,7 +2529,6 @@ bool HexagonLoopRescheduling::isStoreInput(const MachineInstr *MI,
return false;
}
bool HexagonLoopRescheduling::isShuffleOf(unsigned OutR, unsigned InpR) const {
if (!BTP->has(OutR) || !BTP->has(InpR))
return false;
@ -2553,7 +2543,6 @@ bool HexagonLoopRescheduling::isShuffleOf(unsigned OutR, unsigned InpR) const {
return true;
}
bool HexagonLoopRescheduling::isSameShuffle(unsigned OutR1, unsigned InpR1,
unsigned OutR2, unsigned &InpR2) const {
if (!BTP->has(OutR1) || !BTP->has(InpR1) || !BTP->has(OutR2))
@ -2585,7 +2574,6 @@ bool HexagonLoopRescheduling::isSameShuffle(unsigned OutR1, unsigned InpR1,
return true;
}
void HexagonLoopRescheduling::moveGroup(InstrGroup &G, MachineBasicBlock &LB,
MachineBasicBlock &PB, MachineBasicBlock::iterator At, unsigned OldPhiR,
unsigned NewPredR) {
@ -2625,7 +2613,6 @@ void HexagonLoopRescheduling::moveGroup(InstrGroup &G, MachineBasicBlock &LB,
HBS::replaceReg(OldPhiR, RegMap[G.Out.Reg], *MRI);
}
bool HexagonLoopRescheduling::processLoop(LoopCand &C) {
DEBUG(dbgs() << "Processing loop in BB#" << C.LB->getNumber() << "\n");
std::vector<PhiInfo> Phis;
@ -2765,7 +2752,7 @@ bool HexagonLoopRescheduling::processLoop(LoopCand &C) {
auto LoopInpEq = [G] (const PhiInfo &P) -> bool {
return G.Out.Reg == P.LR.Reg;
};
if (find_if(Phis, LoopInpEq) == Phis.end())
if (llvm::find_if(Phis, LoopInpEq) == Phis.end())
continue;
G.Inp.Reg = Inputs.find_first();
@ -2790,7 +2777,7 @@ bool HexagonLoopRescheduling::processLoop(LoopCand &C) {
auto LoopInpEq = [G] (const PhiInfo &P) -> bool {
return G.Out.Reg == P.LR.Reg;
};
auto F = find_if(Phis, LoopInpEq);
auto F = llvm::find_if(Phis, LoopInpEq);
if (F == Phis.end())
continue;
unsigned PrehR = 0;
@ -2830,7 +2817,6 @@ bool HexagonLoopRescheduling::processLoop(LoopCand &C) {
return Changed;
}
bool HexagonLoopRescheduling::runOnMachineFunction(MachineFunction &MF) {
if (skipFunction(*MF.getFunction()))
return false;
@ -2893,4 +2879,3 @@ FunctionPass *llvm::createHexagonLoopRescheduling() {
FunctionPass *llvm::createHexagonBitSimplify() {
return new HexagonBitSimplify();
}

View File

@ -12,17 +12,19 @@
#include "HexagonBlockRanges.h"
#include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h"
#include "llvm/ADT/BitVector.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/Support/Compiler.h"
#include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include <algorithm>
#include <cassert>
#include <iterator>
#include <map>
using namespace llvm;
@ -40,7 +42,6 @@ bool HexagonBlockRanges::IndexRange::overlaps(const IndexRange &A) const {
return false;
}
bool HexagonBlockRanges::IndexRange::contains(const IndexRange &A) const {
if (start() <= A.start()) {
// Treat "None" in the range end as equal to the range start.
@ -52,7 +53,6 @@ bool HexagonBlockRanges::IndexRange::contains(const IndexRange &A) const {
return false;
}
void HexagonBlockRanges::IndexRange::merge(const IndexRange &A) {
// Allow merging adjacent ranges.
assert(end() == A.start() || overlaps(A));
@ -70,14 +70,12 @@ void HexagonBlockRanges::IndexRange::merge(const IndexRange &A) {
Fixed = true;
}
void HexagonBlockRanges::RangeList::include(const RangeList &RL) {
for (auto &R : RL)
if (!is_contained(*this, R))
push_back(R);
}
// Merge all overlapping ranges in the list, so that all that remains
// is a list of disjoint ranges.
void HexagonBlockRanges::RangeList::unionize(bool MergeAdjacent) {
@ -101,7 +99,6 @@ void HexagonBlockRanges::RangeList::unionize(bool MergeAdjacent) {
}
}
// Compute a range A-B and add it to the list.
void HexagonBlockRanges::RangeList::addsub(const IndexRange &A,
const IndexRange &B) {
@ -138,7 +135,6 @@ void HexagonBlockRanges::RangeList::addsub(const IndexRange &A,
}
}
// Subtract a given range from each element in the list.
void HexagonBlockRanges::RangeList::subtract(const IndexRange &Range) {
// Cannot assume that the list is unionized (i.e. contains only non-
@ -156,7 +152,6 @@ void HexagonBlockRanges::RangeList::subtract(const IndexRange &Range) {
include(T);
}
HexagonBlockRanges::InstrIndexMap::InstrIndexMap(MachineBasicBlock &B)
: Block(B) {
IndexType Idx = IndexType::First;
@ -171,13 +166,11 @@ HexagonBlockRanges::InstrIndexMap::InstrIndexMap(MachineBasicBlock &B)
Last = B.empty() ? IndexType::None : unsigned(Idx)-1;
}
MachineInstr *HexagonBlockRanges::InstrIndexMap::getInstr(IndexType Idx) const {
auto F = Map.find(Idx);
return (F != Map.end()) ? F->second : 0;
return (F != Map.end()) ? F->second : nullptr;
}
HexagonBlockRanges::IndexType HexagonBlockRanges::InstrIndexMap::getIndex(
MachineInstr *MI) const {
for (auto &I : Map)
@ -186,7 +179,6 @@ HexagonBlockRanges::IndexType HexagonBlockRanges::InstrIndexMap::getIndex(
return IndexType::None;
}
HexagonBlockRanges::IndexType HexagonBlockRanges::InstrIndexMap::getPrevIndex(
IndexType Idx) const {
assert (Idx != IndexType::None);
@ -199,7 +191,6 @@ HexagonBlockRanges::IndexType HexagonBlockRanges::InstrIndexMap::getPrevIndex(
return unsigned(Idx)-1;
}
HexagonBlockRanges::IndexType HexagonBlockRanges::InstrIndexMap::getNextIndex(
IndexType Idx) const {
assert (Idx != IndexType::None);
@ -210,7 +201,6 @@ HexagonBlockRanges::IndexType HexagonBlockRanges::InstrIndexMap::getNextIndex(
return unsigned(Idx)+1;
}
void HexagonBlockRanges::InstrIndexMap::replaceInstr(MachineInstr *OldMI,
MachineInstr *NewMI) {
for (auto &I : Map) {
@ -224,7 +214,6 @@ void HexagonBlockRanges::InstrIndexMap::replaceInstr(MachineInstr *OldMI,
}
}
HexagonBlockRanges::HexagonBlockRanges(MachineFunction &mf)
: MF(mf), HST(mf.getSubtarget<HexagonSubtarget>()),
TII(*HST.getInstrInfo()), TRI(*HST.getRegisterInfo()),
@ -239,7 +228,6 @@ HexagonBlockRanges::HexagonBlockRanges(MachineFunction &mf)
}
}
HexagonBlockRanges::RegisterSet HexagonBlockRanges::getLiveIns(
const MachineBasicBlock &B, const MachineRegisterInfo &MRI,
const TargetRegisterInfo &TRI) {
@ -267,7 +255,6 @@ HexagonBlockRanges::RegisterSet HexagonBlockRanges::getLiveIns(
return LiveIns;
}
HexagonBlockRanges::RegisterSet HexagonBlockRanges::expandToSubRegs(
RegisterRef R, const MachineRegisterInfo &MRI,
const TargetRegisterInfo &TRI) {
@ -297,7 +284,6 @@ HexagonBlockRanges::RegisterSet HexagonBlockRanges::expandToSubRegs(
return SRs;
}
void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap,
RegToRangeMap &LiveMap) {
std::map<RegisterRef,IndexType> LastDef, LastUse;
@ -379,7 +365,6 @@ void HexagonBlockRanges::computeInitialLiveRanges(InstrIndexMap &IndexMap,
P.second.unionize();
}
HexagonBlockRanges::RegToRangeMap HexagonBlockRanges::computeLiveMap(
InstrIndexMap &IndexMap) {
RegToRangeMap LiveMap;
@ -390,7 +375,6 @@ HexagonBlockRanges::RegToRangeMap HexagonBlockRanges::computeLiveMap(
return LiveMap;
}
HexagonBlockRanges::RegToRangeMap HexagonBlockRanges::computeDeadMap(
InstrIndexMap &IndexMap, RegToRangeMap &LiveMap) {
RegToRangeMap DeadMap;

View File

@ -1,4 +1,4 @@
//===--- HexagonBlockRanges.h ---------------------------------------------===//
//===--- HexagonBlockRanges.h -----------------------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
@ -11,23 +11,21 @@
#include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/MC/MCRegisterInfo.h" // For MCPhysReg.
#include <cassert>
#include <map>
#include <set>
#include <vector>
#include <utility>
namespace llvm {
class Function;
class HexagonSubtarget;
class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
class MCInstrDesc;
class raw_ostream;
class TargetInstrInfo;
class TargetRegisterClass;
class TargetRegisterInfo;
class Type;
class HexagonSubtarget;
class MachineBasicBlock;
class MachineFunction;
class MachineInstr;
class raw_ostream;
class TargetInstrInfo;
class TargetRegisterInfo;
struct HexagonBlockRanges {
HexagonBlockRanges(MachineFunction &MF);
@ -50,10 +48,12 @@ struct HexagonBlockRanges {
Exit = 2,
First = 11 // 10th + 1st
};
static bool isInstr(IndexType X) { return X.Index >= First; }
IndexType() : Index(None) {}
IndexType(unsigned Idx) : Index(Idx) {}
static bool isInstr(IndexType X) { return X.Index >= First; }
operator unsigned() const;
bool operator== (unsigned x) const;
bool operator== (IndexType Idx) const;
@ -76,21 +76,23 @@ struct HexagonBlockRanges {
// register is dead.
class IndexRange : public std::pair<IndexType,IndexType> {
public:
IndexRange() : Fixed(false), TiedEnd(false) {}
IndexRange() = default;
IndexRange(IndexType Start, IndexType End, bool F = false, bool T = false)
: std::pair<IndexType,IndexType>(Start, End), Fixed(F), TiedEnd(T) {}
IndexType start() const { return first; }
IndexType end() const { return second; }
bool operator< (const IndexRange &A) const {
return start() < A.start();
}
bool overlaps(const IndexRange &A) const;
bool contains(const IndexRange &A) const;
void merge(const IndexRange &A);
bool Fixed; // Can be renamed? "Fixed" means "no".
bool TiedEnd; // The end is not a use, but a dead def tied to a use.
bool Fixed = false; // Can be renamed? "Fixed" means "no".
bool TiedEnd = false; // The end is not a use, but a dead def tied to a use.
private:
void setStart(const IndexType &S) { first = S; }
@ -107,6 +109,7 @@ struct HexagonBlockRanges {
void add(const IndexRange &Range) {
push_back(Range);
}
void include(const RangeList &RL);
void unionize(bool MergeAdjacent = false);
void subtract(const IndexRange &Range);
@ -118,6 +121,7 @@ struct HexagonBlockRanges {
class InstrIndexMap {
public:
InstrIndexMap(MachineBasicBlock &B);
MachineInstr *getInstr(IndexType Idx) const;
IndexType getIndex(MachineInstr *MI) const;
MachineBasicBlock &getBlock() const { return Block; }
@ -126,6 +130,7 @@ struct HexagonBlockRanges {
void replaceInstr(MachineInstr *OldMI, MachineInstr *NewMI);
friend raw_ostream &operator<< (raw_ostream &OS, const InstrIndexMap &Map);
IndexType First, Last;
private:
@ -144,6 +149,7 @@ struct HexagonBlockRanges {
: Map(M), TRI(I) {}
friend raw_ostream &operator<< (raw_ostream &OS, const PrintRangeMap &P);
private:
const RegToRangeMap &Map;
const TargetRegisterInfo &TRI;
@ -163,7 +169,6 @@ private:
BitVector Reserved;
};
inline HexagonBlockRanges::IndexType::operator unsigned() const {
assert(Index >= First);
return Index;
@ -224,7 +229,6 @@ inline bool HexagonBlockRanges::IndexType::operator<= (IndexType Idx) const {
return operator==(Idx) || operator<(Idx);
}
raw_ostream &operator<< (raw_ostream &OS, HexagonBlockRanges::IndexType Idx);
raw_ostream &operator<< (raw_ostream &OS,
const HexagonBlockRanges::IndexRange &IR);
@ -235,6 +239,6 @@ raw_ostream &operator<< (raw_ostream &OS,
raw_ostream &operator<< (raw_ostream &OS,
const HexagonBlockRanges::PrintRangeMap &P);
} // namespace llvm
} // end namespace llvm
#endif
#endif // HEXAGON_BLOCK_RANGES_H

View File

@ -12,15 +12,23 @@
#include "Hexagon.h"
#include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/PassSupport.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include <cassert>
#include <cstdint>
#include <cstdlib>
#include <iterator>
using namespace llvm;
@ -30,14 +38,18 @@ static cl::opt<uint32_t> BranchRelaxSafetyBuffer("branch-relax-safety-buffer",
cl::init(200), cl::Hidden, cl::ZeroOrMore, cl::desc("safety buffer size"));
namespace llvm {
FunctionPass *createHexagonBranchRelaxation();
void initializeHexagonBranchRelaxationPass(PassRegistry&);
}
} // end namespace llvm
namespace {
struct HexagonBranchRelaxation : public MachineFunctionPass {
public:
static char ID;
HexagonBranchRelaxation() : MachineFunctionPass(ID) {
initializeHexagonBranchRelaxationPass(*PassRegistry::getPassRegistry());
}
@ -67,6 +79,7 @@ namespace {
};
char HexagonBranchRelaxation::ID = 0;
} // end anonymous namespace
INITIALIZE_PASS(HexagonBranchRelaxation, "hexagon-brelax",
@ -76,7 +89,6 @@ FunctionPass *llvm::createHexagonBranchRelaxation() {
return new HexagonBranchRelaxation();
}
bool HexagonBranchRelaxation::runOnMachineFunction(MachineFunction &MF) {
DEBUG(dbgs() << "****** Hexagon Branch Relaxation ******\n");
@ -89,7 +101,6 @@ bool HexagonBranchRelaxation::runOnMachineFunction(MachineFunction &MF) {
return Changed;
}
void HexagonBranchRelaxation::computeOffset(MachineFunction &MF,
DenseMap<MachineBasicBlock*, unsigned> &OffsetMap) {
// offset of the current instruction from the start.
@ -108,7 +119,6 @@ void HexagonBranchRelaxation::computeOffset(MachineFunction &MF,
}
}
/// relaxBranches - For Hexagon, if the jump target/loop label is too far from
/// the jump/loop instruction then, we need to make sure that we have constant
/// extenders set for jumps and loops.
@ -124,7 +134,6 @@ bool HexagonBranchRelaxation::relaxBranches(MachineFunction &MF) {
return reGenerateBranch(MF, BlockToInstOffset);
}
/// Check if a given instruction is:
/// - a jump to a distant target
/// - that exceeds its immediate range
@ -144,7 +153,7 @@ bool HexagonBranchRelaxation::isJumpOutOfRange(MachineInstr &MI,
// Number of instructions times typical instruction size.
InstOffset += HII->nonDbgBBSize(&B) * HEXAGON_INSTR_SIZE;
MachineBasicBlock *TBB = NULL, *FBB = NULL;
MachineBasicBlock *TBB = nullptr, *FBB = nullptr;
SmallVector<MachineOperand, 4> Cond;
// Try to analyze this branch.
@ -176,7 +185,6 @@ bool HexagonBranchRelaxation::isJumpOutOfRange(MachineInstr &MI,
return false;
}
bool HexagonBranchRelaxation::reGenerateBranch(MachineFunction &MF,
DenseMap<MachineBasicBlock*, unsigned> &BlockToInstOffset) {
bool Changed = false;

View File

@ -9,29 +9,42 @@
#define DEBUG_TYPE "commgep"
#include "llvm/Pass.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/FoldingSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/Constant.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Verifier.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.h"
#include "llvm/Support/Allocator.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Scalar.h"
#include "llvm/Transforms/Utils/Local.h"
#include <algorithm>
#include <cassert>
#include <cstddef>
#include <cstdint>
#include <iterator>
#include <map>
#include <set>
#include <utility>
#include <vector>
#include "HexagonTargetMachine.h"
using namespace llvm;
static cl::opt<bool> OptSpeculate("commgep-speculate", cl::init(true),
@ -44,10 +57,13 @@ static cl::opt<bool> OptEnableConst("commgep-const", cl::init(true),
cl::Hidden, cl::ZeroOrMore);
namespace llvm {
void initializeHexagonCommonGEPPass(PassRegistry&);
}
} // end namespace llvm
namespace {
struct GepNode;
typedef std::set<GepNode*> NodeSet;
typedef std::map<GepNode*,Value*> NodeToValueMap;
@ -59,7 +75,7 @@ namespace {
// Numbering map for gep nodes. Used to keep track of ordering for
// gep nodes.
struct NodeOrdering {
NodeOrdering() : LastNum(0) {}
NodeOrdering() = default;
void insert(const GepNode *N) { Map.insert(std::make_pair(N, ++LastNum)); }
void clear() { Map.clear(); }
@ -72,19 +88,21 @@ namespace {
private:
std::map<const GepNode *, unsigned> Map;
unsigned LastNum;
unsigned LastNum = 0;
};
class HexagonCommonGEP : public FunctionPass {
public:
static char ID;
HexagonCommonGEP() : FunctionPass(ID) {
initializeHexagonCommonGEPPass(*PassRegistry::getPassRegistry());
}
virtual bool runOnFunction(Function &F);
virtual StringRef getPassName() const { return "Hexagon Common GEP"; }
virtual void getAnalysisUsage(AnalysisUsage &AU) const {
bool runOnFunction(Function &F) override;
StringRef getPassName() const override { return "Hexagon Common GEP"; }
void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<DominatorTreeWrapperPass>();
AU.addPreserved<DominatorTreeWrapperPass>();
AU.addRequired<PostDominatorTreeWrapperPass>();
@ -137,8 +155,8 @@ namespace {
PostDominatorTree *PDT;
Function *Fn;
};
}
} // end anonymous namespace
char HexagonCommonGEP::ID = 0;
INITIALIZE_PASS_BEGIN(HexagonCommonGEP, "hcommgep", "Hexagon Common GEP",
@ -150,6 +168,7 @@ INITIALIZE_PASS_END(HexagonCommonGEP, "hcommgep", "Hexagon Common GEP",
false, false)
namespace {
struct GepNode {
enum {
None = 0,
@ -166,17 +185,17 @@ namespace {
Value *Idx;
Type *PTy; // Type of the pointer operand.
GepNode() : Flags(0), Parent(0), Idx(0), PTy(0) {}
GepNode() : Flags(0), Parent(nullptr), Idx(nullptr), PTy(nullptr) {}
GepNode(const GepNode *N) : Flags(N->Flags), Idx(N->Idx), PTy(N->PTy) {
if (Flags & Root)
BaseVal = N->BaseVal;
else
Parent = N->Parent;
}
friend raw_ostream &operator<< (raw_ostream &OS, const GepNode &GN);
};
Type *next_type(Type *Ty, Value *Idx) {
if (auto *PTy = dyn_cast<PointerType>(Ty))
return PTy->getElementType();
@ -193,7 +212,6 @@ namespace {
return NextTy;
}
raw_ostream &operator<< (raw_ostream &OS, const GepNode &GN) {
OS << "{ {";
bool Comma = false;
@ -240,7 +258,6 @@ namespace {
return OS;
}
template <typename NodeContainer>
void dump_node_container(raw_ostream &OS, const NodeContainer &S) {
typedef typename NodeContainer::const_iterator const_iterator;
@ -255,7 +272,6 @@ namespace {
return OS;
}
raw_ostream &operator<< (raw_ostream &OS,
const NodeToUsesMap &M) LLVM_ATTRIBUTE_UNUSED;
raw_ostream &operator<< (raw_ostream &OS, const NodeToUsesMap &M){
@ -275,23 +291,22 @@ namespace {
return OS;
}
struct in_set {
in_set(const NodeSet &S) : NS(S) {}
bool operator() (GepNode *N) const {
return NS.find(N) != NS.end();
}
private:
const NodeSet &NS;
};
}
} // end anonymous namespace
inline void *operator new(size_t, SpecificBumpPtrAllocator<GepNode> &A) {
return A.Allocate();
}
void HexagonCommonGEP::getBlockTraversalOrder(BasicBlock *Root,
ValueVect &Order) {
// Compute block ordering for a typical DT-based traversal of the flow
@ -306,7 +321,6 @@ void HexagonCommonGEP::getBlockTraversalOrder(BasicBlock *Root,
getBlockTraversalOrder((*I)->getBlock(), Order);
}
bool HexagonCommonGEP::isHandledGepForm(GetElementPtrInst *GepI) {
// No vector GEPs.
if (!GepI->getType()->isPointerTy())
@ -317,7 +331,6 @@ bool HexagonCommonGEP::isHandledGepForm(GetElementPtrInst *GepI) {
return true;
}
void HexagonCommonGEP::processGepInst(GetElementPtrInst *GepI,
ValueToNodeMap &NM) {
DEBUG(dbgs() << "Visiting GEP: " << *GepI << '\n');
@ -383,7 +396,6 @@ void HexagonCommonGEP::processGepInst(GetElementPtrInst *GepI,
NM.insert(std::make_pair(GepI, PN));
}
void HexagonCommonGEP::collect() {
// Establish depth-first traversal order of the dominator tree.
ValueVect BO;
@ -407,10 +419,8 @@ void HexagonCommonGEP::collect() {
DEBUG(dbgs() << "Gep nodes after initial collection:\n" << Nodes);
}
namespace {
void invert_find_roots(const NodeVect &Nodes, NodeChildrenMap &NCM,
NodeVect &Roots) {
static void invert_find_roots(const NodeVect &Nodes, NodeChildrenMap &NCM,
NodeVect &Roots) {
typedef NodeVect::const_iterator const_iterator;
for (const_iterator I = Nodes.begin(), E = Nodes.end(); I != E; ++I) {
GepNode *N = *I;
@ -421,9 +431,10 @@ namespace {
GepNode *PN = N->Parent;
NCM[PN].push_back(N);
}
}
}
void nodes_for_root(GepNode *Root, NodeChildrenMap &NCM, NodeSet &Nodes) {
static void nodes_for_root(GepNode *Root, NodeChildrenMap &NCM,
NodeSet &Nodes) {
NodeVect Work;
Work.push_back(Root);
Nodes.insert(Root);
@ -438,41 +449,43 @@ namespace {
Nodes.insert(CF->second.begin(), CF->second.end());
}
}
}
}
namespace {
typedef std::set<NodeSet> NodeSymRel;
typedef std::pair<GepNode*,GepNode*> NodePair;
typedef std::set<NodePair> NodePairSet;
const NodeSet *node_class(GepNode *N, NodeSymRel &Rel) {
} // end anonymous namespace
static const NodeSet *node_class(GepNode *N, NodeSymRel &Rel) {
for (NodeSymRel::iterator I = Rel.begin(), E = Rel.end(); I != E; ++I)
if (I->count(N))
return &*I;
return 0;
}
return nullptr;
}
// Create an ordered pair of GepNode pointers. The pair will be used in
// determining equality. The only purpose of the ordering is to eliminate
// duplication due to the commutativity of equality/non-equality.
NodePair node_pair(GepNode *N1, GepNode *N2) {
static NodePair node_pair(GepNode *N1, GepNode *N2) {
uintptr_t P1 = uintptr_t(N1), P2 = uintptr_t(N2);
if (P1 <= P2)
return std::make_pair(N1, N2);
return std::make_pair(N2, N1);
}
}
unsigned node_hash(GepNode *N) {
static unsigned node_hash(GepNode *N) {
// Include everything except flags and parent.
FoldingSetNodeID ID;
ID.AddPointer(N->Idx);
ID.AddPointer(N->PTy);
return ID.ComputeHash();
}
}
bool node_eq(GepNode *N1, GepNode *N2, NodePairSet &Eq, NodePairSet &Ne) {
static bool node_eq(GepNode *N1, GepNode *N2, NodePairSet &Eq,
NodePairSet &Ne) {
// Don't cache the result for nodes with different hashes. The hash
// comparison is fast enough.
if (node_hash(N1) != node_hash(N2))
@ -504,10 +517,8 @@ namespace {
return true;
}
return false;
}
}
void HexagonCommonGEP::common() {
// The essence of this commoning is finding gep nodes that are equal.
// To do this we need to compare all pairs of nodes. To save time,
@ -571,7 +582,6 @@ void HexagonCommonGEP::common() {
}
});
// Create a projection from a NodeSet to the minimal element in it.
typedef std::map<const NodeSet*,GepNode*> ProjMap;
ProjMap PM;
@ -644,10 +654,8 @@ void HexagonCommonGEP::common() {
DEBUG(dbgs() << "Gep nodes after post-commoning cleanup:\n" << Nodes);
}
namespace {
template <typename T>
BasicBlock *nearest_common_dominator(DominatorTree *DT, T &Blocks) {
template <typename T>
static BasicBlock *nearest_common_dominator(DominatorTree *DT, T &Blocks) {
DEBUG({
dbgs() << "NCD of {";
for (typename T::iterator I = Blocks.begin(), E = Blocks.end();
@ -660,23 +668,23 @@ namespace {
dbgs() << " }\n";
});
// Allow null basic blocks in Blocks. In such cases, return 0.
// Allow null basic blocks in Blocks. In such cases, return nullptr.
typename T::iterator I = Blocks.begin(), E = Blocks.end();
if (I == E || !*I)
return 0;
return nullptr;
BasicBlock *Dom = cast<BasicBlock>(*I);
while (++I != E) {
BasicBlock *B = cast_or_null<BasicBlock>(*I);
Dom = B ? DT->findNearestCommonDominator(Dom, B) : 0;
Dom = B ? DT->findNearestCommonDominator(Dom, B) : nullptr;
if (!Dom)
return 0;
return nullptr;
}
DEBUG(dbgs() << "computed:" << Dom->getName() << '\n');
return Dom;
}
}
template <typename T>
BasicBlock *nearest_common_dominatee(DominatorTree *DT, T &Blocks) {
template <typename T>
static BasicBlock *nearest_common_dominatee(DominatorTree *DT, T &Blocks) {
// If two blocks, A and B, dominate a block C, then A dominates B,
// or B dominates A.
typename T::iterator I = Blocks.begin(), E = Blocks.end();
@ -693,16 +701,16 @@ namespace {
if (DT->dominates(B, DomB))
continue;
if (!DT->dominates(DomB, B))
return 0;
return nullptr;
DomB = B;
}
return DomB;
}
}
// Find the first use in B of any value from Values. If no such use,
// return B->end().
template <typename T>
BasicBlock::iterator first_use_of_in_block(T &Values, BasicBlock *B) {
// Find the first use in B of any value from Values. If no such use,
// return B->end().
template <typename T>
static BasicBlock::iterator first_use_of_in_block(T &Values, BasicBlock *B) {
BasicBlock::iterator FirstUse = B->end(), BEnd = B->end();
typedef typename T::iterator iterator;
for (iterator I = Values.begin(), E = Values.end(); I != E; ++I) {
@ -724,20 +732,18 @@ namespace {
FirstUse = It;
}
return FirstUse;
}
bool is_empty(const BasicBlock *B) {
return B->empty() || (&*B->begin() == B->getTerminator());
}
}
static bool is_empty(const BasicBlock *B) {
return B->empty() || (&*B->begin() == B->getTerminator());
}
BasicBlock *HexagonCommonGEP::recalculatePlacement(GepNode *Node,
NodeChildrenMap &NCM, NodeToValueMap &Loc) {
DEBUG(dbgs() << "Loc for node:" << Node << '\n');
// Recalculate the placement for Node, assuming that the locations of
// its children in Loc are valid.
// Return 0 if there is no valid placement for Node (for example, it
// Return nullptr if there is no valid placement for Node (for example, it
// uses an index value that is not available at the location required
// to dominate all children, etc.).
@ -780,11 +786,11 @@ BasicBlock *HexagonCommonGEP::recalculatePlacement(GepNode *Node,
BasicBlock *DomB = nearest_common_dominator(DT, Bs);
if (!DomB)
return 0;
return nullptr;
// Check if the index used by Node dominates the computed dominator.
Instruction *IdxI = dyn_cast<Instruction>(Node->Idx);
if (IdxI && !DT->dominates(IdxI->getParent(), DomB))
return 0;
return nullptr;
// Avoid putting nodes into empty blocks.
while (is_empty(DomB)) {
@ -799,7 +805,6 @@ BasicBlock *HexagonCommonGEP::recalculatePlacement(GepNode *Node,
return DomB;
}
BasicBlock *HexagonCommonGEP::recalculatePlacementRec(GepNode *Node,
NodeChildrenMap &NCM, NodeToValueMap &Loc) {
DEBUG(dbgs() << "LocRec begin for node:" << Node << '\n');
@ -816,7 +821,6 @@ BasicBlock *HexagonCommonGEP::recalculatePlacementRec(GepNode *Node,
return LB;
}
bool HexagonCommonGEP::isInvariantIn(Value *Val, Loop *L) {
if (isa<Constant>(Val) || isa<Argument>(Val))
return true;
@ -827,7 +831,6 @@ bool HexagonCommonGEP::isInvariantIn(Value *Val, Loop *L) {
return DT->properlyDominates(DefB, HdrB);
}
bool HexagonCommonGEP::isInvariantIn(GepNode *Node, Loop *L) {
if (Node->Flags & GepNode::Root)
if (!isInvariantIn(Node->BaseVal, L))
@ -835,7 +838,6 @@ bool HexagonCommonGEP::isInvariantIn(GepNode *Node, Loop *L) {
return isInvariantIn(Node->Idx, L);
}
bool HexagonCommonGEP::isInMainPath(BasicBlock *B, Loop *L) {
BasicBlock *HB = L->getHeader();
BasicBlock *LB = L->getLoopLatch();
@ -847,21 +849,17 @@ bool HexagonCommonGEP::isInMainPath(BasicBlock *B, Loop *L) {
return false;
}
namespace {
BasicBlock *preheader(DominatorTree *DT, Loop *L) {
if (BasicBlock *PH = L->getLoopPreheader())
return PH;
if (!OptSpeculate)
return 0;
DomTreeNode *DN = DT->getNode(L->getHeader());
if (!DN)
return 0;
return DN->getIDom()->getBlock();
}
static BasicBlock *preheader(DominatorTree *DT, Loop *L) {
if (BasicBlock *PH = L->getLoopPreheader())
return PH;
if (!OptSpeculate)
return nullptr;
DomTreeNode *DN = DT->getNode(L->getHeader());
if (!DN)
return nullptr;
return DN->getIDom()->getBlock();
}
BasicBlock *HexagonCommonGEP::adjustForInvariance(GepNode *Node,
NodeChildrenMap &NCM, NodeToValueMap &Loc) {
// Find the "topmost" location for Node: it must be dominated by both,
@ -911,10 +909,11 @@ BasicBlock *HexagonCommonGEP::adjustForInvariance(GepNode *Node,
return LocB;
}
namespace {
struct LocationAsBlock {
LocationAsBlock(const NodeToValueMap &L) : Map(L) {}
const NodeToValueMap &Map;
};
@ -934,8 +933,8 @@ namespace {
inline bool is_constant(GepNode *N) {
return isa<ConstantInt>(N->Idx);
}
}
} // end anonymous namespace
void HexagonCommonGEP::separateChainForNode(GepNode *Node, Use *U,
NodeToValueMap &Loc) {
@ -945,7 +944,7 @@ void HexagonCommonGEP::separateChainForNode(GepNode *Node, Use *U,
BasicBlock *PB = cast<Instruction>(R)->getParent();
GepNode *N = Node;
GepNode *C = 0, *NewNode = 0;
GepNode *C = nullptr, *NewNode = nullptr;
while (is_constant(N) && !(N->Flags & GepNode::Root)) {
// XXX if (single-use) dont-replicate;
GepNode *NewN = new (*Mem) GepNode(N);
@ -989,7 +988,6 @@ void HexagonCommonGEP::separateChainForNode(GepNode *Node, Use *U,
Uses[NewNode] = NewUs;
}
void HexagonCommonGEP::separateConstantChains(GepNode *Node,
NodeChildrenMap &NCM, NodeToValueMap &Loc) {
// First approximation: extract all chains.
@ -1043,7 +1041,6 @@ void HexagonCommonGEP::separateConstantChains(GepNode *Node,
}
}
void HexagonCommonGEP::computeNodePlacement(NodeToValueMap &Loc) {
// Compute the inverse of the Node.Parent links. Also, collect the set
// of root nodes.
@ -1078,7 +1075,6 @@ void HexagonCommonGEP::computeNodePlacement(NodeToValueMap &Loc) {
DEBUG(dbgs() << "Final node placement:\n" << LocationAsBlock(Loc));
}
Value *HexagonCommonGEP::fabricateGEP(NodeVect &NA, BasicBlock::iterator At,
BasicBlock *LocB) {
DEBUG(dbgs() << "Fabricating GEP in " << LocB->getName()
@ -1087,7 +1083,7 @@ Value *HexagonCommonGEP::fabricateGEP(NodeVect &NA, BasicBlock::iterator At,
GepNode *RN = NA[0];
assert((RN->Flags & GepNode::Root) && "Creating GEP for non-root");
Value *NewInst = 0;
Value *NewInst = nullptr;
Value *Input = RN->BaseVal;
Value **IdxList = new Value*[Num+1];
unsigned nax = 0;
@ -1126,7 +1122,6 @@ Value *HexagonCommonGEP::fabricateGEP(NodeVect &NA, BasicBlock::iterator At,
return NewInst;
}
void HexagonCommonGEP::getAllUsersForNode(GepNode *Node, ValueVect &Values,
NodeChildrenMap &NCM) {
NodeVect Work;
@ -1151,7 +1146,6 @@ void HexagonCommonGEP::getAllUsersForNode(GepNode *Node, ValueVect &Values,
}
}
void HexagonCommonGEP::materialize(NodeToValueMap &Loc) {
DEBUG(dbgs() << "Nodes before materialization:\n" << Nodes << '\n');
NodeChildrenMap NCM;
@ -1190,7 +1184,7 @@ void HexagonCommonGEP::materialize(NodeToValueMap &Loc) {
break;
GepNode *Child = CF->second.front();
BasicBlock *ChildB = cast_or_null<BasicBlock>(Loc[Child]);
if (ChildB != 0 && LastB != ChildB)
if (ChildB != nullptr && LastB != ChildB)
break;
Last = Child;
} while (true);
@ -1234,7 +1228,6 @@ void HexagonCommonGEP::materialize(NodeToValueMap &Loc) {
}
}
void HexagonCommonGEP::removeDeadCode() {
ValueVect BO;
BO.push_back(&Fn->front());
@ -1263,7 +1256,6 @@ void HexagonCommonGEP::removeDeadCode() {
}
}
bool HexagonCommonGEP::runOnFunction(Function &F) {
if (skipFunction(F))
return false;
@ -1302,9 +1294,10 @@ bool HexagonCommonGEP::runOnFunction(Function &F) {
return true;
}
namespace llvm {
FunctionPass *createHexagonCommonGEP() {
return new HexagonCommonGEP();
}
}
} // end namespace llvm