diff --git a/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp b/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp index a58c072709d..becc086c81b 100644 --- a/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp +++ b/lib/Target/Hexagon/AsmParser/HexagonAsmParser.cpp @@ -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 +#include +#include +#include +#include +#include +#include +#include using namespace llvm; @@ -65,8 +79,8 @@ static cl::opt 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(&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(&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 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(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(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 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 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 Tokens; + SmallVector 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; diff --git a/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp b/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp index 5c3e5df3ead..c05fbc1d775 100644 --- a/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp +++ b/lib/Target/Hexagon/Disassembler/HexagonDisassembler.cpp @@ -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 +#include +#include +#include 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 const MCII; std::unique_ptr 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(Decoder); } -MCContext &contextFromDecoder(void const *Decoder) { + +static MCContext &contextFromDecoder(void const *Decoder) { return disassembler(Decoder).getContext(); } -} DecodeStatus HexagonDisassembler::getSingleInstruction( MCInst &MI, MCInst &MCB, ArrayRef 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 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 -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; diff --git a/lib/Target/Hexagon/HexagonBitSimplify.cpp b/lib/Target/Hexagon/HexagonBitSimplify.cpp index b1c63eb5ea8..fe7278fde1b 100644 --- a/lib/Target/Hexagon/HexagonBitSimplify.cpp +++ b/lib/Target/Hexagon/HexagonBitSimplify.cpp @@ -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 +#include +#include +#include +#include +#include +#include using namespace llvm; @@ -28,16 +48,19 @@ static cl::opt 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(); AU.addPreserved(); 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 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 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::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::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 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(); } - diff --git a/lib/Target/Hexagon/HexagonBlockRanges.cpp b/lib/Target/Hexagon/HexagonBlockRanges.cpp index bfa2275a423..938bdca054f 100644 --- a/lib/Target/Hexagon/HexagonBlockRanges.cpp +++ b/lib/Target/Hexagon/HexagonBlockRanges.cpp @@ -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 +#include +#include #include 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()), 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 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; diff --git a/lib/Target/Hexagon/HexagonBlockRanges.h b/lib/Target/Hexagon/HexagonBlockRanges.h index 4d18cf5abe8..717480314d1 100644 --- a/lib/Target/Hexagon/HexagonBlockRanges.h +++ b/lib/Target/Hexagon/HexagonBlockRanges.h @@ -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 #include #include #include +#include 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 { public: - IndexRange() : Fixed(false), TiedEnd(false) {} + IndexRange() = default; IndexRange(IndexType Start, IndexType End, bool F = false, bool T = false) : std::pair(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 ⤅ 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 diff --git a/lib/Target/Hexagon/HexagonBranchRelaxation.cpp b/lib/Target/Hexagon/HexagonBranchRelaxation.cpp index f1599753f87..84af4b14b9f 100644 --- a/lib/Target/Hexagon/HexagonBranchRelaxation.cpp +++ b/lib/Target/Hexagon/HexagonBranchRelaxation.cpp @@ -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 +#include +#include +#include using namespace llvm; @@ -30,14 +38,18 @@ static cl::opt 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 &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 Cond; // Try to analyze this branch. @@ -176,7 +185,6 @@ bool HexagonBranchRelaxation::isJumpOutOfRange(MachineInstr &MI, return false; } - bool HexagonBranchRelaxation::reGenerateBranch(MachineFunction &MF, DenseMap &BlockToInstOffset) { bool Changed = false; diff --git a/lib/Target/Hexagon/HexagonCommonGEP.cpp b/lib/Target/Hexagon/HexagonCommonGEP.cpp index 9336e0fd50b..3c9b1ec5953 100644 --- a/lib/Target/Hexagon/HexagonCommonGEP.cpp +++ b/lib/Target/Hexagon/HexagonCommonGEP.cpp @@ -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 +#include +#include +#include +#include #include #include +#include #include -#include "HexagonTargetMachine.h" - using namespace llvm; static cl::opt OptSpeculate("commgep-speculate", cl::init(true), @@ -44,10 +57,13 @@ static cl::opt OptEnableConst("commgep-const", cl::init(true), cl::Hidden, cl::ZeroOrMore); namespace llvm { + void initializeHexagonCommonGEPPass(PassRegistry&); -} + +} // end namespace llvm namespace { + struct GepNode; typedef std::set NodeSet; typedef std::map 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 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(); AU.addPreserved(); AU.addRequired(); @@ -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(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 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 &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 NodeSymRel; typedef std::pair NodePair; typedef std::set 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 ProjMap; ProjMap PM; @@ -644,10 +654,8 @@ void HexagonCommonGEP::common() { DEBUG(dbgs() << "Gep nodes after post-commoning cleanup:\n" << Nodes); } - -namespace { - template - BasicBlock *nearest_common_dominator(DominatorTree *DT, T &Blocks) { +template +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(*I); while (++I != E) { BasicBlock *B = cast_or_null(*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 - BasicBlock *nearest_common_dominatee(DominatorTree *DT, T &Blocks) { +template +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 - 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 +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(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(Val) || isa(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 ⤅ }; @@ -934,8 +933,8 @@ namespace { inline bool is_constant(GepNode *N) { return isa(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(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(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