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

llvm-svn: 314467
This commit is contained in:
Eugene Zelenko 2017-09-28 22:27:31 +00:00
parent 4664d77316
commit 3b87336a0c
14 changed files with 398 additions and 313 deletions

View File

@ -7,8 +7,6 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define DEBUG_TYPE "hbr"
#include "HexagonBlockRanges.h" #include "HexagonBlockRanges.h"
#include "HexagonInstrInfo.h" #include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h" #include "HexagonSubtarget.h"
@ -17,6 +15,7 @@
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h" #include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/MC/MCRegisterInfo.h" #include "llvm/MC/MCRegisterInfo.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
@ -31,6 +30,8 @@
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "hbr"
bool HexagonBlockRanges::IndexRange::overlaps(const IndexRange &A) const { bool HexagonBlockRanges::IndexRange::overlaps(const IndexRange &A) const {
// If A contains start(), or "this" contains A.start(), then overlap. // If A contains start(), or "this" contains A.start(), then overlap.
IndexType S = start(), E = end(), AS = A.start(), AE = A.end(); IndexType S = start(), E = end(), AS = A.start(), AE = A.end();

View File

@ -1,4 +1,4 @@
//===--- HexagonBlockRanges.h -----------------------------------*- C++ -*-===// //===- HexagonBlockRanges.h -------------------------------------*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -6,11 +6,11 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#ifndef HEXAGON_BLOCK_RANGES_H
#define HEXAGON_BLOCK_RANGES_H #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H
#define LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H
#include "llvm/ADT/BitVector.h" #include "llvm/ADT/BitVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include <cassert> #include <cassert>
#include <map> #include <map>
#include <set> #include <set>
@ -23,6 +23,7 @@ class HexagonSubtarget;
class MachineBasicBlock; class MachineBasicBlock;
class MachineFunction; class MachineFunction;
class MachineInstr; class MachineInstr;
class MachineRegisterInfo;
class raw_ostream; class raw_ostream;
class TargetInstrInfo; class TargetInstrInfo;
class TargetRegisterInfo; class TargetRegisterInfo;
@ -32,11 +33,12 @@ struct HexagonBlockRanges {
struct RegisterRef { struct RegisterRef {
unsigned Reg, Sub; unsigned Reg, Sub;
bool operator<(RegisterRef R) const { bool operator<(RegisterRef R) const {
return Reg < R.Reg || (Reg == R.Reg && Sub < R.Sub); return Reg < R.Reg || (Reg == R.Reg && Sub < R.Sub);
} }
}; };
typedef std::set<RegisterRef> RegisterSet; using RegisterSet = std::set<RegisterRef>;
// This is to represent an "index", which is an abstraction of a position // This is to represent an "index", which is an abstraction of a position
// of an instruction within a basic block. // of an instruction within a basic block.
@ -49,7 +51,7 @@ struct HexagonBlockRanges {
First = 11 // 10th + 1st First = 11 // 10th + 1st
}; };
IndexType() : Index(None) {} IndexType() {}
IndexType(unsigned Idx) : Index(Idx) {} IndexType(unsigned Idx) : Index(Idx) {}
static bool isInstr(IndexType X) { return X.Index >= First; } static bool isInstr(IndexType X) { return X.Index >= First; }
@ -68,7 +70,7 @@ struct HexagonBlockRanges {
bool operator> (IndexType Idx) const; bool operator> (IndexType Idx) const;
bool operator>= (IndexType Idx) const; bool operator>= (IndexType Idx) const;
unsigned Index; unsigned Index = None;
}; };
// A range of indices, essentially a representation of a live range. // A range of indices, essentially a representation of a live range.
@ -138,7 +140,8 @@ struct HexagonBlockRanges {
std::map<IndexType,MachineInstr*> Map; std::map<IndexType,MachineInstr*> Map;
}; };
typedef std::map<RegisterRef,RangeList> RegToRangeMap; using RegToRangeMap = std::map<RegisterRef, RangeList>;
RegToRangeMap computeLiveMap(InstrIndexMap &IndexMap); RegToRangeMap computeLiveMap(InstrIndexMap &IndexMap);
RegToRangeMap computeDeadMap(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap); RegToRangeMap computeDeadMap(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap);
static RegisterSet expandToSubRegs(RegisterRef R, static RegisterSet expandToSubRegs(RegisterRef R,
@ -241,4 +244,4 @@ raw_ostream &operator<< (raw_ostream &OS,
} // end namespace llvm } // end namespace llvm
#endif // HEXAGON_BLOCK_RANGES_H #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H

View File

@ -1,4 +1,5 @@
//===-- HexagonCFGOptimizer.cpp - CFG optimizations -----------------------===// //===- HexagonCFGOptimizer.cpp - CFG optimizations ------------------------===//
//
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
// This file is distributed under the University of Illinois Open Source // This file is distributed under the University of Illinois Open Source
@ -7,53 +8,54 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "Hexagon.h" #include "Hexagon.h"
#include "HexagonMachineFunctionInfo.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "HexagonSubtarget.h" #include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "HexagonTargetMachine.h" #include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/Pass.h"
#include "llvm/CodeGen/Passes.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h" #include "llvm/Target/TargetSubtargetInfo.h"
#include "llvm/Target/TargetRegisterInfo.h" #include <cassert>
#include <vector>
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "hexagon_cfg" #define DEBUG_TYPE "hexagon_cfg"
namespace llvm { namespace llvm {
FunctionPass *createHexagonCFGOptimizer();
void initializeHexagonCFGOptimizerPass(PassRegistry&);
}
FunctionPass *createHexagonCFGOptimizer();
void initializeHexagonCFGOptimizerPass(PassRegistry&);
} // end namespace llvm
namespace { namespace {
class HexagonCFGOptimizer : public MachineFunctionPass { class HexagonCFGOptimizer : public MachineFunctionPass {
private: private:
void InvertAndChangeJumpTarget(MachineInstr &, MachineBasicBlock *); void InvertAndChangeJumpTarget(MachineInstr &, MachineBasicBlock *);
bool isOnFallThroughPath(MachineBasicBlock *MBB); bool isOnFallThroughPath(MachineBasicBlock *MBB);
public: public:
static char ID; static char ID;
HexagonCFGOptimizer() : MachineFunctionPass(ID) { HexagonCFGOptimizer() : MachineFunctionPass(ID) {
initializeHexagonCFGOptimizerPass(*PassRegistry::getPassRegistry()); initializeHexagonCFGOptimizerPass(*PassRegistry::getPassRegistry());
} }
StringRef getPassName() const override { return "Hexagon CFG Optimizer"; } StringRef getPassName() const override { return "Hexagon CFG Optimizer"; }
bool runOnMachineFunction(MachineFunction &Fn) override; bool runOnMachineFunction(MachineFunction &Fn) override;
MachineFunctionProperties getRequiredProperties() const override { MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set( return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoVRegs); MachineFunctionProperties::Property::NoVRegs);
} }
}; };
} // end anonymous namespace
char HexagonCFGOptimizer::ID = 0; char HexagonCFGOptimizer::ID = 0;
@ -72,7 +74,6 @@ static bool IsConditionalBranch(int Opc) {
return false; return false;
} }
static bool IsUnconditionalJump(int Opc) { static bool IsUnconditionalJump(int Opc) {
return (Opc == Hexagon::J2_jump); return (Opc == Hexagon::J2_jump);
} }
@ -86,19 +87,15 @@ void HexagonCFGOptimizer::InvertAndChangeJumpTarget(
case Hexagon::J2_jumpt: case Hexagon::J2_jumpt:
NewOpcode = Hexagon::J2_jumpf; NewOpcode = Hexagon::J2_jumpf;
break; break;
case Hexagon::J2_jumpf: case Hexagon::J2_jumpf:
NewOpcode = Hexagon::J2_jumpt; NewOpcode = Hexagon::J2_jumpt;
break; break;
case Hexagon::J2_jumptnewpt: case Hexagon::J2_jumptnewpt:
NewOpcode = Hexagon::J2_jumpfnewpt; NewOpcode = Hexagon::J2_jumpfnewpt;
break; break;
case Hexagon::J2_jumpfnewpt: case Hexagon::J2_jumpfnewpt:
NewOpcode = Hexagon::J2_jumptnewpt; NewOpcode = Hexagon::J2_jumptnewpt;
break; break;
default: default:
llvm_unreachable("Cannot handle this case"); llvm_unreachable("Cannot handle this case");
} }
@ -131,8 +128,6 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
MachineInstr &MI = *MII; MachineInstr &MI = *MII;
int Opc = MI.getOpcode(); int Opc = MI.getOpcode();
if (IsConditionalBranch(Opc)) { if (IsConditionalBranch(Opc)) {
//
// (Case 1) Transform the code if the following condition occurs: // (Case 1) Transform the code if the following condition occurs:
// BB1: if (p0) jump BB3 // BB1: if (p0) jump BB3
// ...falls-through to BB2 ... // ...falls-through to BB2 ...
@ -160,7 +155,6 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
// Remove BB2 // Remove BB2
// BB3: ... // BB3: ...
// BB4: ... // BB4: ...
//
unsigned NumSuccs = MBB->succ_size(); unsigned NumSuccs = MBB->succ_size();
MachineBasicBlock::succ_iterator SI = MBB->succ_begin(); MachineBasicBlock::succ_iterator SI = MBB->succ_begin();
MachineBasicBlock* FirstSucc = *SI; MachineBasicBlock* FirstSucc = *SI;
@ -200,7 +194,7 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
// Check if the layout successor of BB2 is BB3. // Check if the layout successor of BB2 is BB3.
bool case1 = LayoutSucc->isLayoutSuccessor(JumpAroundTarget); bool case1 = LayoutSucc->isLayoutSuccessor(JumpAroundTarget);
bool case2 = JumpAroundTarget->isSuccessor(UncondTarget) && bool case2 = JumpAroundTarget->isSuccessor(UncondTarget) &&
JumpAroundTarget->size() >= 1 && !JumpAroundTarget->empty() &&
IsUnconditionalJump(JumpAroundTarget->back().getOpcode()) && IsUnconditionalJump(JumpAroundTarget->back().getOpcode()) &&
JumpAroundTarget->pred_size() == 1 && JumpAroundTarget->pred_size() == 1 &&
JumpAroundTarget->succ_size() == 1; JumpAroundTarget->succ_size() == 1;
@ -223,11 +217,9 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
UncondTarget->moveAfter(JumpAroundTarget); UncondTarget->moveAfter(JumpAroundTarget);
} }
//
// Correct live-in information. Is used by post-RA scheduler // Correct live-in information. Is used by post-RA scheduler
// The live-in to LayoutSucc is now all values live-in to // The live-in to LayoutSucc is now all values live-in to
// JumpAroundTarget. // JumpAroundTarget.
//
std::vector<MachineBasicBlock::RegisterMaskPair> OrigLiveIn( std::vector<MachineBasicBlock::RegisterMaskPair> OrigLiveIn(
LayoutSucc->livein_begin(), LayoutSucc->livein_end()); LayoutSucc->livein_begin(), LayoutSucc->livein_end());
std::vector<MachineBasicBlock::RegisterMaskPair> NewLiveIn( std::vector<MachineBasicBlock::RegisterMaskPair> NewLiveIn(
@ -245,8 +237,6 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
} }
return true; return true;
} }
}
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
// Public Constructor Functions // Public Constructor Functions

View File

@ -1,4 +1,4 @@
//===--- HexagonGenExtract.cpp --------------------------------------------===// //===- HexagonGenExtract.cpp ----------------------------------------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -8,7 +8,7 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "llvm/ADT/APInt.h" #include "llvm/ADT/APInt.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/GraphTraits.h"
#include "llvm/IR/BasicBlock.h" #include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h" #include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h" #include "llvm/IR/Constants.h"
@ -47,8 +47,8 @@ static cl::opt<bool> NeedAnd("extract-needand", cl::init(true), cl::Hidden,
namespace llvm { namespace llvm {
void initializeHexagonGenExtractPass(PassRegistry&); void initializeHexagonGenExtractPass(PassRegistry&);
FunctionPass *createHexagonGenExtract(); FunctionPass *createHexagonGenExtract();
} // end namespace llvm } // end namespace llvm
@ -58,7 +58,7 @@ namespace {
public: public:
static char ID; static char ID;
HexagonGenExtract() : FunctionPass(ID), ExtractCount(0) { HexagonGenExtract() : FunctionPass(ID) {
initializeHexagonGenExtractPass(*PassRegistry::getPassRegistry()); initializeHexagonGenExtractPass(*PassRegistry::getPassRegistry());
} }
@ -78,14 +78,14 @@ namespace {
bool visitBlock(BasicBlock *B); bool visitBlock(BasicBlock *B);
bool convert(Instruction *In); bool convert(Instruction *In);
unsigned ExtractCount; unsigned ExtractCount = 0;
DominatorTree *DT; DominatorTree *DT;
}; };
char HexagonGenExtract::ID = 0;
} // end anonymous namespace } // end anonymous namespace
char HexagonGenExtract::ID = 0;
INITIALIZE_PASS_BEGIN(HexagonGenExtract, "hextract", "Hexagon generate " INITIALIZE_PASS_BEGIN(HexagonGenExtract, "hextract", "Hexagon generate "
"\"extract\" instructions", false, false) "\"extract\" instructions", false, false)
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)

View File

@ -1,4 +1,4 @@
//===-- HexagonInstrInfo.cpp - Hexagon Instruction Information ------------===// //===- HexagonInstrInfo.cpp - Hexagon Instruction Information -------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -13,9 +13,11 @@
#include "HexagonInstrInfo.h" #include "HexagonInstrInfo.h"
#include "Hexagon.h" #include "Hexagon.h"
#include "HexagonFrameLowering.h"
#include "HexagonHazardRecognizer.h" #include "HexagonHazardRecognizer.h"
#include "HexagonRegisterInfo.h" #include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h" #include "HexagonSubtarget.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
@ -32,7 +34,9 @@
#include "llvm/CodeGen/MachineMemOperand.h" #include "llvm/CodeGen/MachineMemOperand.h"
#include "llvm/CodeGen/MachineOperand.h" #include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/MC/MCAsmInfo.h" #include "llvm/MC/MCAsmInfo.h"
#include "llvm/MC/MCInstrDesc.h" #include "llvm/MC/MCInstrDesc.h"
#include "llvm/MC/MCInstrItineraries.h" #include "llvm/MC/MCInstrItineraries.h"
@ -44,12 +48,17 @@
#include "llvm/Support/MathExtras.h" #include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetOpcodes.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Target/TargetSubtargetInfo.h"
#include <cassert> #include <cassert>
#include <cctype> #include <cctype>
#include <cstdint> #include <cstdint>
#include <cstring> #include <cstring>
#include <iterator> #include <iterator>
#include <string>
#include <utility>
using namespace llvm; using namespace llvm;
@ -91,9 +100,7 @@ static cl::opt<bool> UseDFAHazardRec("dfa-hazard-rec",
cl::init(true), cl::Hidden, cl::ZeroOrMore, cl::init(true), cl::Hidden, cl::ZeroOrMore,
cl::desc("Use the DFA based hazard recognizer.")); cl::desc("Use the DFA based hazard recognizer."));
///
/// Constants for Hexagon instructions. /// Constants for Hexagon instructions.
///
const int Hexagon_MEMW_OFFSET_MAX = 4095; const int Hexagon_MEMW_OFFSET_MAX = 4095;
const int Hexagon_MEMW_OFFSET_MIN = -4096; const int Hexagon_MEMW_OFFSET_MIN = -4096;
const int Hexagon_MEMD_OFFSET_MAX = 8191; const int Hexagon_MEMD_OFFSET_MAX = 8191;
@ -339,7 +346,6 @@ unsigned HexagonInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
/// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode /// Cond[0] = Hexagon::CMPEQri_f_Jumpnv_t_V4 -- specific opcode
/// Cond[1] = R /// Cond[1] = R
/// Cond[2] = Imm /// Cond[2] = Imm
///
bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB, bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
MachineBasicBlock *&TBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB, MachineBasicBlock *&FBB,
@ -576,7 +582,7 @@ unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB,
SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs; SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(), MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
VisitedBBs); VisitedBBs);
assert(Loop != 0 && "Inserting an ENDLOOP without a LOOP"); assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
Loop->getOperand(0).setMBB(TBB); Loop->getOperand(0).setMBB(TBB);
// Add the ENDLOOP after the finding the LOOP0. // Add the ENDLOOP after the finding the LOOP0.
BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB); BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
@ -617,7 +623,7 @@ unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB,
SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs; SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(), MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
VisitedBBs); VisitedBBs);
assert(Loop != 0 && "Inserting an ENDLOOP without a LOOP"); assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
Loop->getOperand(0).setMBB(TBB); Loop->getOperand(0).setMBB(TBB);
// Add the ENDLOOP after the finding the LOOP0. // Add the ENDLOOP after the finding the LOOP0.
BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB); BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
@ -1580,7 +1586,6 @@ unsigned HexagonInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
return getInstrTimingClassLatency(ItinData, MI); return getInstrTimingClassLatency(ItinData, MI);
} }
DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState( DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(
const TargetSubtargetInfo &STI) const { const TargetSubtargetInfo &STI) const {
const InstrItineraryData *II = STI.getInstrItineraryData(); const InstrItineraryData *II = STI.getInstrItineraryData();
@ -1672,6 +1677,7 @@ HexagonInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
ArrayRef<std::pair<unsigned, const char*>> ArrayRef<std::pair<unsigned, const char*>>
HexagonInstrInfo::getSerializableDirectMachineOperandTargetFlags() const { HexagonInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
using namespace HexagonII; using namespace HexagonII;
static const std::pair<unsigned, const char*> Flags[] = { static const std::pair<unsigned, const char*> Flags[] = {
{MO_PCREL, "hexagon-pcrel"}, {MO_PCREL, "hexagon-pcrel"},
{MO_GOT, "hexagon-got"}, {MO_GOT, "hexagon-got"},
@ -1690,6 +1696,7 @@ HexagonInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
ArrayRef<std::pair<unsigned, const char*>> ArrayRef<std::pair<unsigned, const char*>>
HexagonInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const { HexagonInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
using namespace HexagonII; using namespace HexagonII;
static const std::pair<unsigned, const char*> Flags[] = { static const std::pair<unsigned, const char*> Flags[] = {
{HMOTF_ConstExtended, "hexagon-ext"} {HMOTF_ConstExtended, "hexagon-ext"}
}; };
@ -1794,13 +1801,13 @@ bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const {
bool HexagonInstrInfo::isDeallocRet(const MachineInstr &MI) const { bool HexagonInstrInfo::isDeallocRet(const MachineInstr &MI) const {
switch (MI.getOpcode()) { switch (MI.getOpcode()) {
case Hexagon::L4_return : case Hexagon::L4_return:
case Hexagon::L4_return_t : case Hexagon::L4_return_t:
case Hexagon::L4_return_f : case Hexagon::L4_return_f:
case Hexagon::L4_return_tnew_pnt : case Hexagon::L4_return_tnew_pnt:
case Hexagon::L4_return_fnew_pnt : case Hexagon::L4_return_fnew_pnt:
case Hexagon::L4_return_tnew_pt : case Hexagon::L4_return_tnew_pt:
case Hexagon::L4_return_fnew_pt : case Hexagon::L4_return_fnew_pt:
return true; return true;
} }
return false; return false;
@ -1950,10 +1957,10 @@ bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr &I,
bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const { bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const {
switch (MI.getOpcode()) { switch (MI.getOpcode()) {
case Hexagon::J2_callr : case Hexagon::J2_callr:
case Hexagon::J2_callrf : case Hexagon::J2_callrf:
case Hexagon::J2_callrt : case Hexagon::J2_callrt:
case Hexagon::PS_call_nr : case Hexagon::PS_call_nr:
return true; return true;
} }
return false; return false;
@ -1961,13 +1968,13 @@ bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const {
bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const { bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const {
switch (MI.getOpcode()) { switch (MI.getOpcode()) {
case Hexagon::L4_return : case Hexagon::L4_return:
case Hexagon::L4_return_t : case Hexagon::L4_return_t:
case Hexagon::L4_return_f : case Hexagon::L4_return_f:
case Hexagon::L4_return_fnew_pnt : case Hexagon::L4_return_fnew_pnt:
case Hexagon::L4_return_fnew_pt : case Hexagon::L4_return_fnew_pt:
case Hexagon::L4_return_tnew_pnt : case Hexagon::L4_return_tnew_pnt:
case Hexagon::L4_return_tnew_pt : case Hexagon::L4_return_tnew_pt:
return true; return true;
} }
return false; return false;
@ -1975,13 +1982,13 @@ bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const {
bool HexagonInstrInfo::isJumpR(const MachineInstr &MI) const { bool HexagonInstrInfo::isJumpR(const MachineInstr &MI) const {
switch (MI.getOpcode()) { switch (MI.getOpcode()) {
case Hexagon::J2_jumpr : case Hexagon::J2_jumpr:
case Hexagon::J2_jumprt : case Hexagon::J2_jumprt:
case Hexagon::J2_jumprf : case Hexagon::J2_jumprf:
case Hexagon::J2_jumprtnewpt : case Hexagon::J2_jumprtnewpt:
case Hexagon::J2_jumprfnewpt : case Hexagon::J2_jumprfnewpt:
case Hexagon::J2_jumprtnew : case Hexagon::J2_jumprtnew:
case Hexagon::J2_jumprfnew : case Hexagon::J2_jumprfnew:
return true; return true;
} }
return false; return false;
@ -2089,24 +2096,24 @@ bool HexagonInstrInfo::isLoopN(const MachineInstr &MI) const {
bool HexagonInstrInfo::isMemOp(const MachineInstr &MI) const { bool HexagonInstrInfo::isMemOp(const MachineInstr &MI) const {
switch (MI.getOpcode()) { switch (MI.getOpcode()) {
default: return false; default: return false;
case Hexagon::L4_iadd_memopw_io : case Hexagon::L4_iadd_memopw_io:
case Hexagon::L4_isub_memopw_io : case Hexagon::L4_isub_memopw_io:
case Hexagon::L4_add_memopw_io : case Hexagon::L4_add_memopw_io:
case Hexagon::L4_sub_memopw_io : case Hexagon::L4_sub_memopw_io:
case Hexagon::L4_and_memopw_io : case Hexagon::L4_and_memopw_io:
case Hexagon::L4_or_memopw_io : case Hexagon::L4_or_memopw_io:
case Hexagon::L4_iadd_memoph_io : case Hexagon::L4_iadd_memoph_io:
case Hexagon::L4_isub_memoph_io : case Hexagon::L4_isub_memoph_io:
case Hexagon::L4_add_memoph_io : case Hexagon::L4_add_memoph_io:
case Hexagon::L4_sub_memoph_io : case Hexagon::L4_sub_memoph_io:
case Hexagon::L4_and_memoph_io : case Hexagon::L4_and_memoph_io:
case Hexagon::L4_or_memoph_io : case Hexagon::L4_or_memoph_io:
case Hexagon::L4_iadd_memopb_io : case Hexagon::L4_iadd_memopb_io:
case Hexagon::L4_isub_memopb_io : case Hexagon::L4_isub_memopb_io:
case Hexagon::L4_add_memopb_io : case Hexagon::L4_add_memopb_io:
case Hexagon::L4_sub_memopb_io : case Hexagon::L4_sub_memopb_io:
case Hexagon::L4_and_memopb_io : case Hexagon::L4_and_memopb_io:
case Hexagon::L4_or_memopb_io : case Hexagon::L4_or_memopb_io:
case Hexagon::L4_ior_memopb_io: case Hexagon::L4_ior_memopb_io:
case Hexagon::L4_ior_memoph_io: case Hexagon::L4_ior_memoph_io:
case Hexagon::L4_ior_memopw_io: case Hexagon::L4_ior_memopw_io:
@ -2293,8 +2300,8 @@ bool HexagonInstrInfo::isSolo(const MachineInstr &MI) const {
bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr &MI) const { bool HexagonInstrInfo::isSpillPredRegOp(const MachineInstr &MI) const {
switch (MI.getOpcode()) { switch (MI.getOpcode()) {
case Hexagon::STriw_pred : case Hexagon::STriw_pred:
case Hexagon::LDriw_pred : case Hexagon::LDriw_pred:
return true; return true;
default: default:
return false; return false;
@ -2357,7 +2364,6 @@ bool HexagonInstrInfo::isHVXVec(const MachineInstr &MI) const {
} }
// Check if the Offset is a valid auto-inc imm by Load/Store Type. // Check if the Offset is a valid auto-inc imm by Load/Store Type.
//
bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, int Offset) const { bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, int Offset) const {
int Size = VT.getSizeInBits() / 8; int Size = VT.getSizeInBits() / 8;
if (Offset % Size != 0) if (Offset % Size != 0)
@ -2469,28 +2475,28 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
return (Offset >= Hexagon_ADDI_OFFSET_MIN) && return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
(Offset <= Hexagon_ADDI_OFFSET_MAX); (Offset <= Hexagon_ADDI_OFFSET_MAX);
case Hexagon::L4_iadd_memopw_io : case Hexagon::L4_iadd_memopw_io:
case Hexagon::L4_isub_memopw_io : case Hexagon::L4_isub_memopw_io:
case Hexagon::L4_add_memopw_io : case Hexagon::L4_add_memopw_io:
case Hexagon::L4_sub_memopw_io : case Hexagon::L4_sub_memopw_io:
case Hexagon::L4_and_memopw_io : case Hexagon::L4_and_memopw_io:
case Hexagon::L4_or_memopw_io : case Hexagon::L4_or_memopw_io:
return (0 <= Offset && Offset <= 255); return (0 <= Offset && Offset <= 255);
case Hexagon::L4_iadd_memoph_io : case Hexagon::L4_iadd_memoph_io:
case Hexagon::L4_isub_memoph_io : case Hexagon::L4_isub_memoph_io:
case Hexagon::L4_add_memoph_io : case Hexagon::L4_add_memoph_io:
case Hexagon::L4_sub_memoph_io : case Hexagon::L4_sub_memoph_io:
case Hexagon::L4_and_memoph_io : case Hexagon::L4_and_memoph_io:
case Hexagon::L4_or_memoph_io : case Hexagon::L4_or_memoph_io:
return (0 <= Offset && Offset <= 127); return (0 <= Offset && Offset <= 127);
case Hexagon::L4_iadd_memopb_io : case Hexagon::L4_iadd_memopb_io:
case Hexagon::L4_isub_memopb_io : case Hexagon::L4_isub_memopb_io:
case Hexagon::L4_add_memopb_io : case Hexagon::L4_add_memopb_io:
case Hexagon::L4_sub_memopb_io : case Hexagon::L4_sub_memopb_io:
case Hexagon::L4_and_memopb_io : case Hexagon::L4_and_memopb_io:
case Hexagon::L4_or_memopb_io : case Hexagon::L4_or_memopb_io:
return (0 <= Offset && Offset <= 63); return (0 <= Offset && Offset <= 63);
// LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of // LDriw_xxx and STriw_xxx are pseudo operations, so it has to take offset of
@ -2714,12 +2720,12 @@ bool HexagonInstrInfo::hasNonExtEquivalent(const MachineInstr &MI) const {
// Check addressing mode and retrieve non-ext equivalent instruction. // Check addressing mode and retrieve non-ext equivalent instruction.
switch (getAddrMode(MI)) { switch (getAddrMode(MI)) {
case HexagonII::Absolute : case HexagonII::Absolute:
// Load/store with absolute addressing mode can be converted into // Load/store with absolute addressing mode can be converted into
// base+offset mode. // base+offset mode.
NonExtOpcode = Hexagon::getBaseWithImmOffset(MI.getOpcode()); NonExtOpcode = Hexagon::getBaseWithImmOffset(MI.getOpcode());
break; break;
case HexagonII::BaseImmOffset : case HexagonII::BaseImmOffset:
// Load/store with base+offset addressing mode can be converted into // Load/store with base+offset addressing mode can be converted into
// base+register offset addressing mode. However left shift operand should // base+register offset addressing mode. However left shift operand should
// be set to 0. // be set to 0.
@ -3081,7 +3087,6 @@ HexagonII::CompoundGroup HexagonInstrInfo::getCompoundCandidateGroup(
case Hexagon::RESTORE_DEALLOC_RET_JMP_V4: case Hexagon::RESTORE_DEALLOC_RET_JMP_V4:
case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC: case Hexagon::RESTORE_DEALLOC_RET_JMP_V4_PIC:
return HexagonII::HCG_C; return HexagonII::HCG_C;
break;
} }
return HexagonII::HCG_None; return HexagonII::HCG_None;
@ -3148,7 +3153,6 @@ int HexagonInstrInfo::getNonDotCurOp(const MachineInstr &MI) const {
return 0; return 0;
} }
// The diagram below shows the steps involved in the conversion of a predicated // The diagram below shows the steps involved in the conversion of a predicated
// store instruction to its .new predicated new-value form. // store instruction to its .new predicated new-value form.
// //
@ -3238,8 +3242,8 @@ int HexagonInstrInfo::getDotNewOp(const MachineInstr &MI) const {
switch (MI.getOpcode()) { switch (MI.getOpcode()) {
default: default:
llvm::report_fatal_error(std::string("Unknown .new type: ") + report_fatal_error(std::string("Unknown .new type: ") +
std::to_string(MI.getOpcode()).c_str()); std::to_string(MI.getOpcode()));
case Hexagon::S4_storerb_ur: case Hexagon::S4_storerb_ur:
return Hexagon::S4_storerbnew_ur; return Hexagon::S4_storerbnew_ur;
@ -3535,12 +3539,12 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(
(Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg))) (Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))
return HexagonII::HSIG_L2; return HexagonII::HSIG_L2;
break; break;
case Hexagon::L4_return_t : case Hexagon::L4_return_t:
case Hexagon::L4_return_f : case Hexagon::L4_return_f:
case Hexagon::L4_return_tnew_pnt : case Hexagon::L4_return_tnew_pnt:
case Hexagon::L4_return_fnew_pnt : case Hexagon::L4_return_fnew_pnt:
case Hexagon::L4_return_tnew_pt : case Hexagon::L4_return_tnew_pt:
case Hexagon::L4_return_fnew_pt : case Hexagon::L4_return_fnew_pt:
// [if ([!]p0[.new])] dealloc_return // [if ([!]p0[.new])] dealloc_return
SrcReg = MI.getOperand(0).getReg(); SrcReg = MI.getOperand(0).getReg();
if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg)) if (Hexagon::PredRegsRegClass.contains(SrcReg) && (Hexagon::P0 == SrcReg))
@ -3869,6 +3873,7 @@ int HexagonInstrInfo::getMaxValue(const MachineInstr &MI) const {
unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr &MI) const { unsigned HexagonInstrInfo::getMemAccessSize(const MachineInstr &MI) const {
using namespace HexagonII; using namespace HexagonII;
const uint64_t F = MI.getDesc().TSFlags; const uint64_t F = MI.getDesc().TSFlags;
unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask; unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask;
unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S)); unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S));
@ -3912,9 +3917,9 @@ short HexagonInstrInfo::getNonExtOpcode(const MachineInstr &MI) const {
if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) { if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
// Check addressing mode and retrieve non-ext equivalent instruction. // Check addressing mode and retrieve non-ext equivalent instruction.
switch (getAddrMode(MI)) { switch (getAddrMode(MI)) {
case HexagonII::Absolute : case HexagonII::Absolute:
return Hexagon::getBaseWithImmOffset(MI.getOpcode()); return Hexagon::getBaseWithImmOffset(MI.getOpcode());
case HexagonII::BaseImmOffset : case HexagonII::BaseImmOffset:
return Hexagon::getBaseWithRegOffset(MI.getOpcode()); return Hexagon::getBaseWithRegOffset(MI.getOpcode());
case HexagonII::BaseLongOffset: case HexagonII::BaseLongOffset:
return Hexagon::getRegShlForm(MI.getOpcode()); return Hexagon::getRegShlForm(MI.getOpcode());

View File

@ -18,8 +18,8 @@
#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineValueType.h" #include "llvm/CodeGen/MachineValueType.h"
#include "llvm/CodeGen/ValueTypes.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include <cstdint> #include <cstdint>
#include <vector> #include <vector>
@ -29,9 +29,12 @@
namespace llvm { namespace llvm {
struct EVT;
class HexagonSubtarget; class HexagonSubtarget;
class HexagonRegisterInfo; class MachineBranchProbabilityInfo;
class MachineFunction;
class MachineInstr;
class MachineOperand;
class TargetRegisterInfo;
class HexagonInstrInfo : public HexagonGenInstrInfo { class HexagonInstrInfo : public HexagonGenInstrInfo {
virtual void anchor(); virtual void anchor();
@ -40,7 +43,6 @@ public:
explicit HexagonInstrInfo(HexagonSubtarget &ST); explicit HexagonInstrInfo(HexagonSubtarget &ST);
/// TargetInstrInfo overrides. /// TargetInstrInfo overrides.
///
/// If the specified machine instruction is a direct /// If the specified machine instruction is a direct
/// load from a stack slot, return the virtual or physical register number of /// load from a stack slot, return the virtual or physical register number of
@ -82,7 +84,6 @@ public:
/// ///
/// If AllowModify is true, then this routine is allowed to modify the basic /// If AllowModify is true, then this routine is allowed to modify the basic
/// block (e.g. delete instructions after the unconditional branch). /// block (e.g. delete instructions after the unconditional branch).
///
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
MachineBasicBlock *&FBB, MachineBasicBlock *&FBB,
SmallVectorImpl<MachineOperand> &Cond, SmallVectorImpl<MachineOperand> &Cond,
@ -249,7 +250,7 @@ public:
/// Allocate and return a hazard recognizer to use for this target when /// Allocate and return a hazard recognizer to use for this target when
/// scheduling the machine instructions after register allocation. /// scheduling the machine instructions after register allocation.
ScheduleHazardRecognizer* ScheduleHazardRecognizer*
CreateTargetPostRAHazardRecognizer(const InstrItineraryData*, CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
const ScheduleDAG *DAG) const override; const ScheduleDAG *DAG) const override;
/// For a comparison instruction, return the source registers /// For a comparison instruction, return the source registers
@ -323,7 +324,6 @@ public:
bool isTailCall(const MachineInstr &MI) const override; bool isTailCall(const MachineInstr &MI) const override;
/// HexagonInstrInfo specifics. /// HexagonInstrInfo specifics.
///
unsigned createVR(MachineFunction* MF, MVT VT) const; unsigned createVR(MachineFunction* MF, MVT VT) const;

View File

@ -13,13 +13,37 @@
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "HexagonMachineScheduler.h" #include "HexagonMachineScheduler.h"
#include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h" #include "HexagonSubtarget.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/CodeGen/TargetSchedule.h"
#include "llvm/IR/Function.h" #include "llvm/IR/Function.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetOpcodes.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include <algorithm>
#include <cassert>
#include <iomanip> #include <iomanip>
#include <limits>
#include <memory>
#include <sstream> #include <sstream>
using namespace llvm;
#define DEBUG_TYPE "machine-scheduler"
static cl::opt<bool> IgnoreBBRegPressure("ignore-bb-reg-pressure", static cl::opt<bool> IgnoreBBRegPressure("ignore-bb-reg-pressure",
cl::Hidden, cl::ZeroOrMore, cl::init(false)); cl::Hidden, cl::ZeroOrMore, cl::init(false));
@ -40,10 +64,6 @@ static cl::opt<bool> DisableTCTie("disable-tc-tie",
static cl::opt<bool> CheckEarlyAvail("check-early-avail", cl::Hidden, static cl::opt<bool> CheckEarlyAvail("check-early-avail", cl::Hidden,
cl::ZeroOrMore, cl::init(true)); cl::ZeroOrMore, cl::init(true));
using namespace llvm;
#define DEBUG_TYPE "machine-scheduler"
/// Save the last formed packet /// Save the last formed packet
void VLIWResourceModel::savePacket() { void VLIWResourceModel::savePacket() {
OldPacket = Packet; OldPacket = Packet;
@ -246,7 +266,7 @@ void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) {
Top.ResourceModel = new VLIWResourceModel(STI, DAG->getSchedModel()); Top.ResourceModel = new VLIWResourceModel(STI, DAG->getSchedModel());
Bot.ResourceModel = new VLIWResourceModel(STI, DAG->getSchedModel()); Bot.ResourceModel = new VLIWResourceModel(STI, DAG->getSchedModel());
assert((!llvm::ForceTopDown || !llvm::ForceBottomUp) && assert((!ForceTopDown || !ForceBottomUp) &&
"-misched-topdown incompatible with -misched-bottomup"); "-misched-topdown incompatible with -misched-bottomup");
} }
@ -328,7 +348,8 @@ void ConvergingVLIWScheduler::VLIWSchedBoundary::bumpCycle() {
unsigned Width = SchedModel->getIssueWidth(); unsigned Width = SchedModel->getIssueWidth();
IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width; IssueCount = (IssueCount <= Width) ? 0 : IssueCount - Width;
assert(MinReadyCycle < UINT_MAX && "MinReadyCycle uninitialized"); assert(MinReadyCycle < std::numeric_limits<unsigned>::max() &&
"MinReadyCycle uninitialized");
unsigned NextCycle = std::max(CurrCycle + 1, MinReadyCycle); unsigned NextCycle = std::max(CurrCycle + 1, MinReadyCycle);
if (!HazardRec->isEnabled()) { if (!HazardRec->isEnabled()) {
@ -383,7 +404,7 @@ void ConvergingVLIWScheduler::VLIWSchedBoundary::bumpNode(SUnit *SU) {
void ConvergingVLIWScheduler::VLIWSchedBoundary::releasePending() { void ConvergingVLIWScheduler::VLIWSchedBoundary::releasePending() {
// If the available queue is empty, it is safe to reset MinReadyCycle. // If the available queue is empty, it is safe to reset MinReadyCycle.
if (Available.empty()) if (Available.empty())
MinReadyCycle = UINT_MAX; MinReadyCycle = std::numeric_limits<unsigned>::max();
// Check to see if any of the pending instructions are ready to issue. If // Check to see if any of the pending instructions are ready to issue. If
// so, add them to the available queue. // so, add them to the available queue.
@ -883,7 +904,7 @@ SUnit *ConvergingVLIWScheduler::pickNode(bool &IsTopNode) {
return nullptr; return nullptr;
} }
SUnit *SU; SUnit *SU;
if (llvm::ForceTopDown) { if (ForceTopDown) {
SU = Top.pickOnlyChoice(); SU = Top.pickOnlyChoice();
if (!SU) { if (!SU) {
SchedCandidate TopCand; SchedCandidate TopCand;
@ -894,7 +915,7 @@ SUnit *ConvergingVLIWScheduler::pickNode(bool &IsTopNode) {
SU = TopCand.SU; SU = TopCand.SU;
} }
IsTopNode = true; IsTopNode = true;
} else if (llvm::ForceBottomUp) { } else if (ForceBottomUp) {
SU = Bot.pickOnlyChoice(); SU = Bot.pickOnlyChoice();
if (!SU) { if (!SU) {
SchedCandidate BotCand; SchedCandidate BotCand;

View File

@ -1,4 +1,4 @@
//===-- HexagonMachineScheduler.h - Custom Hexagon MI scheduler. ----===// //===- HexagonMachineScheduler.h - Custom Hexagon MI scheduler --*- C++ -*-===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -14,25 +14,25 @@
#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H #ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H
#define LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H #define LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H
#include "llvm/ADT/PriorityQueue.h" #include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/ADT/Twine.h"
#include "llvm/CodeGen/LiveIntervalAnalysis.h" #include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineScheduler.h" #include "llvm/CodeGen/MachineScheduler.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/CodeGen/RegisterClassInfo.h"
#include "llvm/CodeGen/RegisterPressure.h" #include "llvm/CodeGen/RegisterPressure.h"
#include "llvm/CodeGen/ResourcePriorityQueue.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
#include "llvm/CodeGen/ScheduleHazardRecognizer.h" #include "llvm/CodeGen/ScheduleHazardRecognizer.h"
#include "llvm/Support/Debug.h" #include "llvm/CodeGen/TargetSchedule.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
using namespace llvm; #include <algorithm>
#include <cassert>
#include <limits>
#include <memory>
#include <vector>
namespace llvm { namespace llvm {
class SUnit;
class VLIWResourceModel { class VLIWResourceModel {
/// ResourcesModel - Represents VLIW state. /// ResourcesModel - Represents VLIW state.
/// Not limited to VLIW targets per se, but assumes /// Not limited to VLIW targets per se, but assumes
@ -43,19 +43,18 @@ class VLIWResourceModel {
/// Local packet/bundle model. Purely /// Local packet/bundle model. Purely
/// internal to the MI schedulre at the time. /// internal to the MI schedulre at the time.
std::vector<SUnit*> Packet; std::vector<SUnit *> Packet;
/// Total packets created. /// Total packets created.
unsigned TotalPackets; unsigned TotalPackets = 0;
public: public:
/// Save the last formed packet. /// Save the last formed packet.
std::vector<SUnit*> OldPacket; std::vector<SUnit *> OldPacket;
public:
VLIWResourceModel(const TargetSubtargetInfo &STI, const TargetSchedModel *SM) VLIWResourceModel(const TargetSubtargetInfo &STI, const TargetSchedModel *SM)
: SchedModel(SM), TotalPackets(0) { : SchedModel(SM) {
ResourcesModel = STI.getInstrInfo()->CreateTargetScheduleState(STI); ResourcesModel = STI.getInstrInfo()->CreateTargetScheduleState(STI);
// This hard requirement could be relaxed, // This hard requirement could be relaxed,
// but for now do not let it proceed. // but for now do not let it proceed.
@ -89,7 +88,6 @@ public:
bool reserveResources(SUnit *SU); bool reserveResources(SUnit *SU);
void savePacket(); void savePacket();
unsigned getTotalPackets() const { return TotalPackets; } unsigned getTotalPackets() const { return TotalPackets; }
bool isInPacket(SUnit *SU) const { return is_contained(Packet, SU); } bool isInPacket(SUnit *SU) const { return is_contained(Packet, SU); }
}; };
@ -114,20 +112,19 @@ public:
/// ConvergingVLIWScheduler shrinks the unscheduled zone using heuristics /// ConvergingVLIWScheduler shrinks the unscheduled zone using heuristics
/// to balance the schedule. /// to balance the schedule.
class ConvergingVLIWScheduler : public MachineSchedStrategy { class ConvergingVLIWScheduler : public MachineSchedStrategy {
/// Store the state used by ConvergingVLIWScheduler heuristics, required /// Store the state used by ConvergingVLIWScheduler heuristics, required
/// for the lifetime of one invocation of pickNode(). /// for the lifetime of one invocation of pickNode().
struct SchedCandidate { struct SchedCandidate {
// The best SUnit candidate. // The best SUnit candidate.
SUnit *SU; SUnit *SU = nullptr;
// Register pressure values for the best candidate. // Register pressure values for the best candidate.
RegPressureDelta RPDelta; RegPressureDelta RPDelta;
// Best scheduling cost. // Best scheduling cost.
int SCost; int SCost = 0;
SchedCandidate(): SU(nullptr), SCost(0) {} SchedCandidate() = default;
}; };
/// Represent the type of SchedCandidate found within a single queue. /// Represent the type of SchedCandidate found within a single queue.
enum CandResult { enum CandResult {
@ -138,33 +135,30 @@ class ConvergingVLIWScheduler : public MachineSchedStrategy {
/// current cycle in whichever direction at has moved, and maintains the state /// current cycle in whichever direction at has moved, and maintains the state
/// of "hazards" and other interlocks at the current cycle. /// of "hazards" and other interlocks at the current cycle.
struct VLIWSchedBoundary { struct VLIWSchedBoundary {
VLIWMachineScheduler *DAG; VLIWMachineScheduler *DAG = nullptr;
const TargetSchedModel *SchedModel; const TargetSchedModel *SchedModel = nullptr;
ReadyQueue Available; ReadyQueue Available;
ReadyQueue Pending; ReadyQueue Pending;
bool CheckPending; bool CheckPending = false;
ScheduleHazardRecognizer *HazardRec; ScheduleHazardRecognizer *HazardRec = nullptr;
VLIWResourceModel *ResourceModel; VLIWResourceModel *ResourceModel = nullptr;
unsigned CurrCycle; unsigned CurrCycle = 0;
unsigned IssueCount; unsigned IssueCount = 0;
/// MinReadyCycle - Cycle of the soonest available instruction. /// MinReadyCycle - Cycle of the soonest available instruction.
unsigned MinReadyCycle; unsigned MinReadyCycle = std::numeric_limits<unsigned>::max();
// Remember the greatest min operand latency. // Remember the greatest min operand latency.
unsigned MaxMinLatency; unsigned MaxMinLatency = 0;
/// Pending queues extend the ready queues with the same ID and the /// Pending queues extend the ready queues with the same ID and the
/// PendingFlag set. /// PendingFlag set.
VLIWSchedBoundary(unsigned ID, const Twine &Name): VLIWSchedBoundary(unsigned ID, const Twine &Name)
DAG(nullptr), SchedModel(nullptr), Available(ID, Name+".A"), : Available(ID, Name+".A"),
Pending(ID << ConvergingVLIWScheduler::LogMaxQID, Name+".P"), Pending(ID << ConvergingVLIWScheduler::LogMaxQID, Name+".P") {}
CheckPending(false), HazardRec(nullptr), ResourceModel(nullptr),
CurrCycle(0), IssueCount(0),
MinReadyCycle(UINT_MAX), MaxMinLatency(0) {}
~VLIWSchedBoundary() { ~VLIWSchedBoundary() {
delete ResourceModel; delete ResourceModel;
@ -196,8 +190,8 @@ class ConvergingVLIWScheduler : public MachineSchedStrategy {
SUnit *pickOnlyChoice(); SUnit *pickOnlyChoice();
}; };
VLIWMachineScheduler *DAG; VLIWMachineScheduler *DAG = nullptr;
const TargetSchedModel *SchedModel; const TargetSchedModel *SchedModel = nullptr;
// State of the top and bottom scheduled instruction boundaries. // State of the top and bottom scheduled instruction boundaries.
VLIWSchedBoundary Top; VLIWSchedBoundary Top;
@ -211,9 +205,7 @@ public:
LogMaxQID = 2 LogMaxQID = 2
}; };
ConvergingVLIWScheduler() ConvergingVLIWScheduler() : Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
: DAG(nullptr), SchedModel(nullptr), Top(TopQID, "TopQ"),
Bot(BotQID, "BotQ") {}
void initialize(ScheduleDAGMI *dag) override; void initialize(ScheduleDAGMI *dag) override;
@ -249,6 +241,6 @@ protected:
#endif #endif
}; };
} // namespace } // end namespace llvm
#endif #endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H

View File

@ -1,4 +1,4 @@
//===----- HexagonNewValueJump.cpp - Hexagon Backend New Value Jump -------===// //===- HexagonNewValueJump.cpp - Hexagon Backend New Value Jump -----------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -19,28 +19,36 @@
// all, it collapses compare and jump instruction into a new valu jump // all, it collapses compare and jump instruction into a new valu jump
// intstructions. // intstructions.
// //
//
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "Hexagon.h" #include "Hexagon.h"
#include "HexagonInstrInfo.h" #include "HexagonInstrInfo.h"
#include "HexagonMachineFunctionInfo.h"
#include "HexagonRegisterInfo.h" #include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
#include "llvm/ADT/Statistic.h" #include "llvm/ADT/Statistic.h"
#include "llvm/CodeGen/LiveVariables.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineInstrBuilder.h" #include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/Passes.h" #include "llvm/IR/DebugLoc.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h" #include "llvm/MC/MCInstrDesc.h"
#include "llvm/PassSupport.h" #include "llvm/Pass.h"
#include "llvm/Support/BranchProbability.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetInstrInfo.h" #include "llvm/Target/TargetOpcodes.h"
#include "llvm/Target/TargetMachine.h"
#include "llvm/Target/TargetRegisterInfo.h" #include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include <cassert>
#include <cstdint>
#include <iterator>
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "hexagon-nvj" #define DEBUG_TYPE "hexagon-nvj"
@ -56,12 +64,14 @@ static cl::opt<bool> DisableNewValueJumps("disable-nvjump", cl::Hidden,
cl::desc("Disable New Value Jumps")); cl::desc("Disable New Value Jumps"));
namespace llvm { namespace llvm {
FunctionPass *createHexagonNewValueJump();
void initializeHexagonNewValueJumpPass(PassRegistry&);
}
FunctionPass *createHexagonNewValueJump();
void initializeHexagonNewValueJumpPass(PassRegistry&);
} // end namespace llvm
namespace { namespace {
struct HexagonNewValueJump : public MachineFunctionPass { struct HexagonNewValueJump : public MachineFunctionPass {
static char ID; static char ID;
@ -75,6 +85,7 @@ namespace {
StringRef getPassName() const override { return "Hexagon NewValueJump"; } StringRef getPassName() const override { return "Hexagon NewValueJump"; }
bool runOnMachineFunction(MachineFunction &Fn) override; bool runOnMachineFunction(MachineFunction &Fn) override;
MachineFunctionProperties getRequiredProperties() const override { MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set( return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoVRegs); MachineFunctionProperties::Property::NoVRegs);
@ -90,7 +101,7 @@ namespace {
bool isNewValueJumpCandidate(const MachineInstr &MI) const; bool isNewValueJumpCandidate(const MachineInstr &MI) const;
}; };
} // end of anonymous namespace } // end anonymous namespace
char HexagonNewValueJump::ID = 0; char HexagonNewValueJump::ID = 0;
@ -100,7 +111,6 @@ INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
INITIALIZE_PASS_END(HexagonNewValueJump, "hexagon-nvj", INITIALIZE_PASS_END(HexagonNewValueJump, "hexagon-nvj",
"Hexagon NewValueJump", false, false) "Hexagon NewValueJump", false, false)
// We have identified this II could be feeder to NVJ, // We have identified this II could be feeder to NVJ,
// verify that it can be. // verify that it can be.
static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII, static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
@ -109,7 +119,6 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
MachineBasicBlock::iterator end, MachineBasicBlock::iterator end,
MachineBasicBlock::iterator skip, MachineBasicBlock::iterator skip,
MachineFunction &MF) { MachineFunction &MF) {
// Predicated instruction can not be feeder to NVJ. // Predicated instruction can not be feeder to NVJ.
if (QII->isPredicated(*II)) if (QII->isPredicated(*II))
return false; return false;
@ -144,7 +153,6 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
// p0 = cmp.eq(r21, #0) // p0 = cmp.eq(r21, #0)
// if (p0.new) jump:t .LBB29_45 // if (p0.new) jump:t .LBB29_45
// and result WAR hazards if converted to New Value Jump. // and result WAR hazards if converted to New Value Jump.
for (unsigned i = 0; i < II->getNumOperands(); ++i) { for (unsigned i = 0; i < II->getNumOperands(); ++i) {
if (II->getOperand(i).isReg() && if (II->getOperand(i).isReg() &&
(II->getOperand(i).isUse() || II->getOperand(i).isDef())) { (II->getOperand(i).isUse() || II->getOperand(i).isDef())) {
@ -171,7 +179,6 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
// 2. feeder to the compare instruction can be moved before jump. // 2. feeder to the compare instruction can be moved before jump.
static bool commonChecksToProhibitNewValueJump(bool afterRA, static bool commonChecksToProhibitNewValueJump(bool afterRA,
MachineBasicBlock::iterator MII) { MachineBasicBlock::iterator MII) {
// If store in path, bail out. // If store in path, bail out.
if (MII->mayStore()) if (MII->mayStore())
return false; return false;
@ -216,7 +223,6 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
bool optLocation, bool optLocation,
MachineBasicBlock::iterator end, MachineBasicBlock::iterator end,
MachineFunction &MF) { MachineFunction &MF) {
MachineInstr &MI = *II; MachineInstr &MI = *II;
// If the second operand of the compare is an imm, make sure it's in the // If the second operand of the compare is an imm, make sure it's in the
@ -417,9 +423,7 @@ bool HexagonNewValueJump::isNewValueJumpCandidate(
} }
} }
bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) { bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
DEBUG(dbgs() << "********** Hexagon New Value Jump **********\n" DEBUG(dbgs() << "********** Hexagon New Value Jump **********\n"
<< "********** Function: " << MF.getName() << "\n"); << "********** Function: " << MF.getName() << "\n");
@ -536,10 +540,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
if (foundJump && !foundCompare && MI.getOperand(0).isReg() && if (foundJump && !foundCompare && MI.getOperand(0).isReg() &&
MI.getOperand(0).getReg() == predReg) { MI.getOperand(0).getReg() == predReg) {
// Not all compares can be new value compare. Arch Spec: 7.6.1.1 // Not all compares can be new value compare. Arch Spec: 7.6.1.1
if (isNewValueJumpCandidate(MI)) { if (isNewValueJumpCandidate(MI)) {
assert( assert(
(MI.getDesc().isCompare()) && (MI.getDesc().isCompare()) &&
"Only compare instruction can be collapsed into New Value Jump"); "Only compare instruction can be collapsed into New Value Jump");
@ -566,7 +568,6 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
} }
if (foundCompare && foundJump) { if (foundCompare && foundJump) {
// If "common" checks fail, bail out on this BB. // If "common" checks fail, bail out on this BB.
if (!commonChecksToProhibitNewValueJump(afterRA, MII)) if (!commonChecksToProhibitNewValueJump(afterRA, MII))
break; break;

View File

@ -1,4 +1,4 @@
//===--- HexagonStoreWidening.cpp------------------------------------------===// //===- HexagonStoreWidening.cpp -------------------------------------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -27,7 +27,6 @@
#include "HexagonRegisterInfo.h" #include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h" #include "HexagonSubtarget.h"
#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallPtrSet.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/Analysis/MemoryLocation.h" #include "llvm/Analysis/MemoryLocation.h"
#include "llvm/CodeGen/MachineBasicBlock.h" #include "llvm/CodeGen/MachineBasicBlock.h"
@ -55,8 +54,8 @@ using namespace llvm;
namespace llvm { namespace llvm {
FunctionPass *createHexagonStoreWidening(); FunctionPass *createHexagonStoreWidening();
void initializeHexagonStoreWideningPass(PassRegistry&); void initializeHexagonStoreWideningPass(PassRegistry&);
} // end namespace llvm } // end namespace llvm
@ -91,8 +90,8 @@ namespace {
private: private:
static const int MaxWideSize = 4; static const int MaxWideSize = 4;
typedef std::vector<MachineInstr*> InstrGroup; using InstrGroup = std::vector<MachineInstr *>;
typedef std::vector<InstrGroup> InstrGroupList; using InstrGroupList = std::vector<InstrGroup>;
bool instrAliased(InstrGroup &Stores, const MachineMemOperand &MMO); bool instrAliased(InstrGroup &Stores, const MachineMemOperand &MMO);
bool instrAliased(InstrGroup &Stores, const MachineInstr *MI); bool instrAliased(InstrGroup &Stores, const MachineInstr *MI);
@ -109,9 +108,15 @@ namespace {
bool storesAreAdjacent(const MachineInstr *S1, const MachineInstr *S2); bool storesAreAdjacent(const MachineInstr *S1, const MachineInstr *S2);
}; };
} // end anonymous namespace
char HexagonStoreWidening::ID = 0; char HexagonStoreWidening::ID = 0;
} // end anonymous namespace INITIALIZE_PASS_BEGIN(HexagonStoreWidening, "hexagon-widen-stores",
"Hexason Store Widening", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(HexagonStoreWidening, "hexagon-widen-stores",
"Hexagon Store Widening", false, false)
// Some local helper functions... // Some local helper functions...
static unsigned getBaseAddressRegister(const MachineInstr *MI) { static unsigned getBaseAddressRegister(const MachineInstr *MI) {
@ -143,12 +148,6 @@ static const MachineMemOperand &getStoreTarget(const MachineInstr *MI) {
return **MI->memoperands_begin(); return **MI->memoperands_begin();
} }
INITIALIZE_PASS_BEGIN(HexagonStoreWidening, "hexagon-widen-stores",
"Hexason Store Widening", false, false)
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
INITIALIZE_PASS_END(HexagonStoreWidening, "hexagon-widen-stores",
"Hexagon Store Widening", false, false)
// Filtering function: any stores whose opcodes are not "approved" of by // Filtering function: any stores whose opcodes are not "approved" of by
// this function will not be subjected to widening. // this function will not be subjected to widening.
inline bool HexagonStoreWidening::handledStoreType(const MachineInstr *MI) { inline bool HexagonStoreWidening::handledStoreType(const MachineInstr *MI) {

View File

@ -1,4 +1,4 @@
//===----- HexagonPacketizer.cpp - vliw packetizer ---------------------===// //===- HexagonPacketizer.cpp - VLIW packetizer ----------------------------===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -16,18 +16,38 @@
// prune the dependence. // prune the dependence.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#include "HexagonVLIWPacketizer.h" #include "HexagonVLIWPacketizer.h"
#include "Hexagon.h"
#include "HexagonInstrInfo.h"
#include "HexagonRegisterInfo.h" #include "HexagonRegisterInfo.h"
#include "HexagonSubtarget.h" #include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h" #include "llvm/ADT/BitVector.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/STLExtras.h"
#include "llvm/Analysis/AliasAnalysis.h" #include "llvm/Analysis/AliasAnalysis.h"
#include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
#include "llvm/CodeGen/MachineDominators.h" #include "llvm/CodeGen/MachineDominators.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineFunctionPass.h" #include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstr.h"
#include "llvm/CodeGen/MachineLoopInfo.h" #include "llvm/CodeGen/MachineLoopInfo.h"
#include "llvm/CodeGen/MachineRegisterInfo.h" #include "llvm/CodeGen/MachineOperand.h"
#include "llvm/CodeGen/Passes.h" #include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/MC/MCInstrDesc.h"
#include "llvm/Pass.h"
#include "llvm/Support/CommandLine.h" #include "llvm/Support/CommandLine.h"
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"
#include <cassert>
#include <cstdint>
#include <iterator>
using namespace llvm; using namespace llvm;
@ -51,15 +71,18 @@ static cl::opt<bool> DisableVecDblNVStores("disable-vecdbl-nv-stores",
extern cl::opt<bool> ScheduleInlineAsm; extern cl::opt<bool> ScheduleInlineAsm;
namespace llvm { namespace llvm {
FunctionPass *createHexagonPacketizer();
void initializeHexagonPacketizerPass(PassRegistry&);
}
FunctionPass *createHexagonPacketizer();
void initializeHexagonPacketizerPass(PassRegistry&);
} // end namespace llvm
namespace { namespace {
class HexagonPacketizer : public MachineFunctionPass { class HexagonPacketizer : public MachineFunctionPass {
public: public:
static char ID; static char ID;
HexagonPacketizer() : MachineFunctionPass(ID) {} HexagonPacketizer() : MachineFunctionPass(ID) {}
void getAnalysisUsage(AnalysisUsage &AU) const override { void getAnalysisUsage(AnalysisUsage &AU) const override {
@ -72,8 +95,10 @@ namespace {
AU.addPreserved<MachineLoopInfo>(); AU.addPreserved<MachineLoopInfo>();
MachineFunctionPass::getAnalysisUsage(AU); MachineFunctionPass::getAnalysisUsage(AU);
} }
StringRef getPassName() const override { return "Hexagon Packetizer"; } StringRef getPassName() const override { return "Hexagon Packetizer"; }
bool runOnMachineFunction(MachineFunction &Fn) override; bool runOnMachineFunction(MachineFunction &Fn) override;
MachineFunctionProperties getRequiredProperties() const override { MachineFunctionProperties getRequiredProperties() const override {
return MachineFunctionProperties().set( return MachineFunctionProperties().set(
MachineFunctionProperties::Property::NoVRegs); MachineFunctionProperties::Property::NoVRegs);
@ -84,8 +109,9 @@ namespace {
const HexagonRegisterInfo *HRI; const HexagonRegisterInfo *HRI;
}; };
char HexagonPacketizer::ID = 0; } // end anonymous namespace
}
char HexagonPacketizer::ID = 0;
INITIALIZE_PASS_BEGIN(HexagonPacketizer, "hexagon-packetizer", INITIALIZE_PASS_BEGIN(HexagonPacketizer, "hexagon-packetizer",
"Hexagon Packetizer", false, false) "Hexagon Packetizer", false, false)
@ -103,9 +129,9 @@ HexagonPacketizerList::HexagonPacketizerList(MachineFunction &MF,
HII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo(); HII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
HRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo(); HRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
addMutation(make_unique<HexagonSubtarget::UsrOverflowMutation>()); addMutation(llvm::make_unique<HexagonSubtarget::UsrOverflowMutation>());
addMutation(make_unique<HexagonSubtarget::HVXMemLatencyMutation>()); addMutation(llvm::make_unique<HexagonSubtarget::HVXMemLatencyMutation>());
addMutation(make_unique<HexagonSubtarget::BankConflictMutation>()); addMutation(llvm::make_unique<HexagonSubtarget::BankConflictMutation>());
} }
// Check if FirstI modifies a register that SecondI reads. // Check if FirstI modifies a register that SecondI reads.
@ -167,7 +193,6 @@ static MachineBasicBlock::iterator moveInstrOut(MachineInstr &MI,
return NextIt; return NextIt;
} }
bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) { bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) {
if (DisablePacketizer || skipFunction(*MF.getFunction())) if (DisablePacketizer || skipFunction(*MF.getFunction()))
return false; return false;
@ -187,7 +212,6 @@ bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) {
// DFA state table should not be empty. // DFA state table should not be empty.
assert(Packetizer.getResourceTracker() && "Empty DFA table!"); assert(Packetizer.getResourceTracker() && "Empty DFA table!");
//
// Loop over all basic blocks and remove KILL pseudo-instructions // Loop over all basic blocks and remove KILL pseudo-instructions
// These instructions confuse the dependence analysis. Consider: // These instructions confuse the dependence analysis. Consider:
// D0 = ... (Insn 0) // D0 = ... (Insn 0)
@ -196,7 +220,6 @@ bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) {
// Here, Insn 1 will result in the dependence graph not emitting an output // Here, Insn 1 will result in the dependence graph not emitting an output
// dependence between Insn 0 and Insn 2. This can lead to incorrect // dependence between Insn 0 and Insn 2. This can lead to incorrect
// packetization // packetization
//
for (auto &MB : MF) { for (auto &MB : MF) {
auto End = MB.end(); auto End = MB.end();
auto MI = MB.begin(); auto MI = MB.begin();
@ -239,7 +262,6 @@ bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) {
return true; return true;
} }
// Reserve resources for a constant extender. Trigger an assertion if the // Reserve resources for a constant extender. Trigger an assertion if the
// reservation fails. // reservation fails.
void HexagonPacketizerList::reserveResourcesForConstExt() { void HexagonPacketizerList::reserveResourcesForConstExt() {
@ -262,7 +284,6 @@ bool HexagonPacketizerList::tryAllocateResourcesForConstExt(bool Reserve) {
return Avail; return Avail;
} }
bool HexagonPacketizerList::isCallDependent(const MachineInstr &MI, bool HexagonPacketizerList::isCallDependent(const MachineInstr &MI,
SDep::Kind DepType, unsigned DepReg) { SDep::Kind DepType, unsigned DepReg) {
// Check for LR dependence. // Check for LR dependence.
@ -308,7 +329,6 @@ static bool isControlFlow(const MachineInstr &MI) {
return MI.getDesc().isTerminator() || MI.getDesc().isCall(); return MI.getDesc().isTerminator() || MI.getDesc().isCall();
} }
/// Returns true if the instruction modifies a callee-saved register. /// Returns true if the instruction modifies a callee-saved register.
static bool doesModifyCalleeSavedReg(const MachineInstr &MI, static bool doesModifyCalleeSavedReg(const MachineInstr &MI,
const TargetRegisterInfo *TRI) { const TargetRegisterInfo *TRI) {
@ -423,7 +443,7 @@ bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr &MI,
bool HexagonPacketizerList::promoteToDotNew(MachineInstr &MI, bool HexagonPacketizerList::promoteToDotNew(MachineInstr &MI,
SDep::Kind DepType, MachineBasicBlock::iterator &MII, SDep::Kind DepType, MachineBasicBlock::iterator &MII,
const TargetRegisterClass* RC) { const TargetRegisterClass* RC) {
assert (DepType == SDep::Data); assert(DepType == SDep::Data);
int NewOpcode; int NewOpcode;
if (RC == &Hexagon::PredRegsRegClass) if (RC == &Hexagon::PredRegsRegClass)
NewOpcode = HII->getDotNewPredOp(MI, MBPI); NewOpcode = HII->getDotNewPredOp(MI, MBPI);
@ -551,7 +571,6 @@ static const MachineOperand &getAbsSetOperand(const MachineInstr &MI) {
return MI.getOperand(1); return MI.getOperand(1);
} }
// Can be new value store? // Can be new value store?
// Following restrictions are to be respected in convert a store into // Following restrictions are to be respected in convert a store into
// a new value store. // a new value store.
@ -869,7 +888,6 @@ bool HexagonPacketizerList::restrictingDepExistInPacket(MachineInstr &MI,
return false; return false;
} }
/// Gets the predicate register of a predicated instruction. /// Gets the predicate register of a predicated instruction.
static unsigned getPredicatedRegister(MachineInstr &MI, static unsigned getPredicatedRegister(MachineInstr &MI,
const HexagonInstrInfo *QII) { const HexagonInstrInfo *QII) {
@ -1015,7 +1033,6 @@ bool HexagonPacketizerList::isSoloInstruction(const MachineInstr &MI) {
return false; return false;
} }
// Quick check if instructions MI and MJ cannot coexist in the same packet. // Quick check if instructions MI and MJ cannot coexist in the same packet.
// Limit the tests to be "one-way", e.g. "if MI->isBranch and MJ->isInlineAsm", // Limit the tests to be "one-way", e.g. "if MI->isBranch and MJ->isInlineAsm",
// but not the symmetric case: "if MJ->isBranch and MI->isInlineAsm". // but not the symmetric case: "if MJ->isBranch and MI->isInlineAsm".
@ -1063,7 +1080,6 @@ static bool cannotCoexistAsymm(const MachineInstr &MI, const MachineInstr &MJ,
return false; return false;
} }
// Full, symmetric check. // Full, symmetric check.
bool HexagonPacketizerList::cannotCoexist(const MachineInstr &MI, bool HexagonPacketizerList::cannotCoexist(const MachineInstr &MI,
const MachineInstr &MJ) { const MachineInstr &MJ) {
@ -1559,7 +1575,7 @@ HexagonPacketizerList::addToPacket(MachineInstr &MI) {
MachineBasicBlock::iterator MII = MI.getIterator(); MachineBasicBlock::iterator MII = MI.getIterator();
MachineBasicBlock *MBB = MI.getParent(); MachineBasicBlock *MBB = MI.getParent();
if (CurrentPacketMIs.size() == 0) if (CurrentPacketMIs.empty())
PacketStalls = false; PacketStalls = false;
PacketStalls |= producesStall(MI); PacketStalls |= producesStall(MI);
@ -1637,7 +1653,6 @@ bool HexagonPacketizerList::shouldAddToPacket(const MachineInstr &MI) {
return !producesStall(MI); return !producesStall(MI);
} }
// V60 forward scheduling. // V60 forward scheduling.
bool HexagonPacketizerList::producesStall(const MachineInstr &I) { bool HexagonPacketizerList::producesStall(const MachineInstr &I) {
// If the packet already stalls, then ignore the stall from a subsequent // If the packet already stalls, then ignore the stall from a subsequent

View File

@ -1,18 +1,33 @@
#ifndef HEXAGONVLIWPACKETIZER_H //===- HexagonPacketizer.h - VLIW packetizer --------------------*- C++ -*-===//
#define HEXAGONVLIWPACKETIZER_H //
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONVLIWPACKETIZER_H
#define LLVM_LIB_TARGET_HEXAGON_HEXAGONVLIWPACKETIZER_H
#include "llvm/CodeGen/DFAPacketizer.h" #include "llvm/CodeGen/DFAPacketizer.h"
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h" #include "llvm/CodeGen/MachineBasicBlock.h"
#include "llvm/CodeGen/ScheduleDAG.h" #include "llvm/CodeGen/ScheduleDAG.h"
#include "llvm/CodeGen/ScheduleDAGInstrs.h" #include <vector>
namespace llvm { namespace llvm {
class HexagonInstrInfo; class HexagonInstrInfo;
class HexagonRegisterInfo; class HexagonRegisterInfo;
class MachineBranchProbabilityInfo;
class MachineFunction;
class MachineInstr;
class MachineLoopInfo;
class TargetRegisterClass;
class HexagonPacketizerList : public VLIWPacketizerList { class HexagonPacketizerList : public VLIWPacketizerList {
// Vector of instructions assigned to the packet that has just been created. // Vector of instructions assigned to the packet that has just been created.
std::vector<MachineInstr*> OldPacketMIs; std::vector<MachineInstr *> OldPacketMIs;
// Has the instruction been promoted to a dot-new instruction. // Has the instruction been promoted to a dot-new instruction.
bool PromotedToDotNew; bool PromotedToDotNew;
@ -48,7 +63,6 @@ private:
const HexagonRegisterInfo *HRI; const HexagonRegisterInfo *HRI;
public: public:
// Ctor.
HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI, HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI,
AliasAnalysis *AA, AliasAnalysis *AA,
const MachineBranchProbabilityInfo *MBPI); const MachineBranchProbabilityInfo *MBPI);
@ -108,9 +122,11 @@ protected:
bool isNewifiable(const MachineInstr &MI, const TargetRegisterClass *NewRC); bool isNewifiable(const MachineInstr &MI, const TargetRegisterClass *NewRC);
bool isCurifiable(MachineInstr &MI); bool isCurifiable(MachineInstr &MI);
bool cannotCoexist(const MachineInstr &MI, const MachineInstr &MJ); bool cannotCoexist(const MachineInstr &MI, const MachineInstr &MJ);
inline bool isPromotedToDotNew() const {
bool isPromotedToDotNew() const {
return PromotedToDotNew; return PromotedToDotNew;
} }
bool tryAllocateResourcesForConstExt(bool Reserve); bool tryAllocateResourcesForConstExt(bool Reserve);
bool canReserveResourcesForConstExt(); bool canReserveResourcesForConstExt();
void reserveResourcesForConstExt(); void reserveResourcesForConstExt();
@ -120,6 +136,7 @@ protected:
bool hasV4SpecificDependence(const MachineInstr &I, const MachineInstr &J); bool hasV4SpecificDependence(const MachineInstr &I, const MachineInstr &J);
bool producesStall(const MachineInstr &MI); bool producesStall(const MachineInstr &MI);
}; };
} // namespace llvm
#endif // HEXAGONVLIWPACKETIZER_H
} // end namespace llvm
#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONVLIWPACKETIZER_H

View File

@ -6,6 +6,7 @@
// License. See LICENSE.TXT for details. // License. See LICENSE.TXT for details.
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
//
// This pass removes the computation of provably redundant expressions that have // This pass removes the computation of provably redundant expressions that have
// been computed earlier in a previous iteration. It relies on the use of PHIs // been computed earlier in a previous iteration. It relies on the use of PHIs
// to identify loop carried dependences. This is scalar replacement for vector // to identify loop carried dependences. This is scalar replacement for vector
@ -112,23 +113,42 @@
// 1. Num of edges in DepChain = Number of Instructions in DepChain = Number of // 1. Num of edges in DepChain = Number of Instructions in DepChain = Number of
// iterations of carried dependence + 1. // iterations of carried dependence + 1.
// 2. All instructions in the DepChain except the last are PHIs. // 2. All instructions in the DepChain except the last are PHIs.
//
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define DEBUG_TYPE "hexagon-vlcr"
#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SetVector.h"
#include "llvm/ADT/Triple.h" #include "llvm/ADT/SmallVector.h"
#include "llvm/ADT/Statistic.h"
#include "llvm/Analysis/LoopInfo.h"
#include "llvm/Analysis/LoopPass.h" #include "llvm/Analysis/LoopPass.h"
#include "llvm/Transforms/Scalar.h" #include "llvm/IR/BasicBlock.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/IRBuilder.h" #include "llvm/IR/IRBuilder.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h" #include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/IntrinsicInst.h"
#include "llvm/ADT/Statistic.h" #include "llvm/IR/Intrinsics.h"
#include <set> #include "llvm/IR/Use.h"
#include "llvm/IR/User.h"
#include "llvm/IR/Value.h"
#include "llvm/Pass.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 <algorithm>
#include <cassert>
#include <cstddef>
#include <map> #include <map>
#include <memory>
#include <set>
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "hexagon-vlcr"
STATISTIC(HexagonNumVectorLoopCarriedReuse, STATISTIC(HexagonNumVectorLoopCarriedReuse,
"Number of values that were reused from a previous iteration."); "Number of values that were reused from a previous iteration.");
@ -136,17 +156,24 @@ static cl::opt<int> HexagonVLCRIterationLim("hexagon-vlcr-iteration-lim",
cl::Hidden, cl::Hidden,
cl::desc("Maximum distance of loop carried dependences that are handled"), cl::desc("Maximum distance of loop carried dependences that are handled"),
cl::init(2), cl::ZeroOrMore); cl::init(2), cl::ZeroOrMore);
namespace llvm { namespace llvm {
void initializeHexagonVectorLoopCarriedReusePass(PassRegistry&);
Pass *createHexagonVectorLoopCarriedReusePass(); void initializeHexagonVectorLoopCarriedReusePass(PassRegistry&);
} Pass *createHexagonVectorLoopCarriedReusePass();
} // end namespace llvm
namespace { namespace {
// See info about DepChain in the comments at the top of this file. // See info about DepChain in the comments at the top of this file.
typedef SmallVector<Instruction *, 4> ChainOfDependences; using ChainOfDependences = SmallVector<Instruction *, 4>;
class DepChain { class DepChain {
ChainOfDependences Chain; ChainOfDependences Chain;
public: public:
bool isIdentical(DepChain &Other) { bool isIdentical(DepChain &Other) const {
if (Other.size() != size()) if (Other.size() != size())
return false; return false;
ChainOfDependences &OtherChain = Other.getChain(); ChainOfDependences &OtherChain = Other.getChain();
@ -156,30 +183,39 @@ namespace {
} }
return true; return true;
} }
ChainOfDependences &getChain() { ChainOfDependences &getChain() {
return Chain; return Chain;
} }
int size() {
int size() const {
return Chain.size(); return Chain.size();
} }
void clear() { void clear() {
Chain.clear(); Chain.clear();
} }
void push_back(Instruction *I) { void push_back(Instruction *I) {
Chain.push_back(I); Chain.push_back(I);
} }
int iterations() {
int iterations() const {
return size() - 1; return size() - 1;
} }
Instruction *front() {
Instruction *front() const {
return Chain.front(); return Chain.front();
} }
Instruction *back() {
Instruction *back() const {
return Chain.back(); return Chain.back();
} }
Instruction *&operator[](const int index) { Instruction *&operator[](const int index) {
return Chain[index]; return Chain[index];
} }
friend raw_ostream &operator<< (raw_ostream &OS, const DepChain &D); friend raw_ostream &operator<< (raw_ostream &OS, const DepChain &D);
}; };
@ -194,19 +230,21 @@ namespace {
OS << *CD[ChainSize-1] << "\n"; OS << *CD[ChainSize-1] << "\n";
return OS; return OS;
} }
}
namespace {
struct ReuseValue { struct ReuseValue {
Instruction *Inst2Replace; Instruction *Inst2Replace = nullptr;
// In the new PHI node that we'll construct this is the value that'll be // In the new PHI node that we'll construct this is the value that'll be
// used over the backedge. This is teh value that gets reused from a // used over the backedge. This is teh value that gets reused from a
// previous iteration. // previous iteration.
Instruction * BackedgeInst; Instruction *BackedgeInst = nullptr;
ReuseValue() : Inst2Replace(nullptr), BackedgeInst(nullptr) {};
ReuseValue() = default;
void reset() { Inst2Replace = nullptr; BackedgeInst = nullptr; } void reset() { Inst2Replace = nullptr; BackedgeInst = nullptr; }
bool isDefined() { return Inst2Replace != nullptr; } bool isDefined() { return Inst2Replace != nullptr; }
}; };
typedef struct ReuseValue ReuseValue;
LLVM_ATTRIBUTE_UNUSED LLVM_ATTRIBUTE_UNUSED
raw_ostream &operator<<(raw_ostream &OS, const ReuseValue &RU) { raw_ostream &operator<<(raw_ostream &OS, const ReuseValue &RU) {
OS << "** ReuseValue ***\n"; OS << "** ReuseValue ***\n";
@ -214,21 +252,21 @@ namespace {
OS << "Backedge Instruction: " << *(RU.BackedgeInst) << "\n"; OS << "Backedge Instruction: " << *(RU.BackedgeInst) << "\n";
return OS; return OS;
} }
}
namespace {
class HexagonVectorLoopCarriedReuse : public LoopPass { class HexagonVectorLoopCarriedReuse : public LoopPass {
public: public:
static char ID; static char ID;
explicit HexagonVectorLoopCarriedReuse() : LoopPass(ID) { explicit HexagonVectorLoopCarriedReuse() : LoopPass(ID) {
PassRegistry *PR = PassRegistry::getPassRegistry(); PassRegistry *PR = PassRegistry::getPassRegistry();
initializeHexagonVectorLoopCarriedReusePass(*PR); initializeHexagonVectorLoopCarriedReusePass(*PR);
} }
StringRef getPassName() const override { StringRef getPassName() const override {
return "Hexagon-specific loop carried reuse for HVX vectors"; return "Hexagon-specific loop carried reuse for HVX vectors";
} }
void getAnalysisUsage(AnalysisUsage &AU) const override { void getAnalysisUsage(AnalysisUsage &AU) const override {
AU.addRequired<LoopInfoWrapperPass>(); AU.addRequired<LoopInfoWrapperPass>();
AU.addRequiredID(LoopSimplifyID); AU.addRequiredID(LoopSimplifyID);
AU.addRequiredID(LCSSAID); AU.addRequiredID(LCSSAID);
@ -254,9 +292,9 @@ namespace {
DepChain *getDepChainBtwn(Instruction *I1, Instruction *I2); DepChain *getDepChainBtwn(Instruction *I1, Instruction *I2);
bool isEquivalentOperation(Instruction *I1, Instruction *I2); bool isEquivalentOperation(Instruction *I1, Instruction *I2);
bool canReplace(Instruction *I); bool canReplace(Instruction *I);
}; };
}
} // end anonymous namespace
char HexagonVectorLoopCarriedReuse::ID = 0; char HexagonVectorLoopCarriedReuse::ID = 0;
@ -276,7 +314,7 @@ bool HexagonVectorLoopCarriedReuse::runOnLoop(Loop *L, LPPassManager &LPM) {
return false; return false;
// Work only on innermost loops. // Work only on innermost loops.
if (L->getSubLoops().size() != 0) if (!L->getSubLoops().empty())
return false; return false;
// Work only on single basic blocks loops. // Work only on single basic blocks loops.
@ -396,8 +434,8 @@ void HexagonVectorLoopCarriedReuse::findValueToReuse() {
} }
} }
ReuseCandidate.reset(); ReuseCandidate.reset();
return;
} }
Value *HexagonVectorLoopCarriedReuse::findValueInBlock(Value *Op, Value *HexagonVectorLoopCarriedReuse::findValueInBlock(Value *Op,
BasicBlock *BB) { BasicBlock *BB) {
PHINode *PN = dyn_cast<PHINode>(Op); PHINode *PN = dyn_cast<PHINode>(Op);
@ -405,6 +443,7 @@ Value *HexagonVectorLoopCarriedReuse::findValueInBlock(Value *Op,
Value *ValueInBlock = PN->getIncomingValueForBlock(BB); Value *ValueInBlock = PN->getIncomingValueForBlock(BB);
return ValueInBlock; return ValueInBlock;
} }
void HexagonVectorLoopCarriedReuse::reuseValue() { void HexagonVectorLoopCarriedReuse::reuseValue() {
DEBUG(dbgs() << ReuseCandidate); DEBUG(dbgs() << ReuseCandidate);
Instruction *Inst2Replace = ReuseCandidate.Inst2Replace; Instruction *Inst2Replace = ReuseCandidate.Inst2Replace;
@ -476,7 +515,7 @@ void HexagonVectorLoopCarriedReuse::reuseValue() {
} }
bool HexagonVectorLoopCarriedReuse::doVLCR() { bool HexagonVectorLoopCarriedReuse::doVLCR() {
assert((CurLoop->getSubLoops().size() == 0) && assert(CurLoop->getSubLoops().empty() &&
"Can do VLCR on the innermost loop only"); "Can do VLCR on the innermost loop only");
assert((CurLoop->getNumBlocks() == 1) && assert((CurLoop->getNumBlocks() == 1) &&
"Can do VLCR only on single block loops"); "Can do VLCR only on single block loops");
@ -502,6 +541,7 @@ bool HexagonVectorLoopCarriedReuse::doVLCR() {
} while (Continue); } while (Continue);
return Changed; return Changed;
} }
void HexagonVectorLoopCarriedReuse::findDepChainFromPHI(Instruction *I, void HexagonVectorLoopCarriedReuse::findDepChainFromPHI(Instruction *I,
DepChain &D) { DepChain &D) {
PHINode *PN = dyn_cast<PHINode>(I); PHINode *PN = dyn_cast<PHINode>(I);
@ -536,7 +576,6 @@ void HexagonVectorLoopCarriedReuse::findDepChainFromPHI(Instruction *I,
D.push_back(PN); D.push_back(PN);
findDepChainFromPHI(BEInst, D); findDepChainFromPHI(BEInst, D);
} }
return;
} }
bool HexagonVectorLoopCarriedReuse::isDepChainBtwn(Instruction *I1, bool HexagonVectorLoopCarriedReuse::isDepChainBtwn(Instruction *I1,
@ -548,6 +587,7 @@ bool HexagonVectorLoopCarriedReuse::isDepChainBtwn(Instruction *I1,
} }
return false; return false;
} }
DepChain *HexagonVectorLoopCarriedReuse::getDepChainBtwn(Instruction *I1, DepChain *HexagonVectorLoopCarriedReuse::getDepChainBtwn(Instruction *I1,
Instruction *I2) { Instruction *I2) {
for (auto *D : Dependences) { for (auto *D : Dependences) {
@ -556,6 +596,7 @@ DepChain *HexagonVectorLoopCarriedReuse::getDepChainBtwn(Instruction *I1,
} }
return nullptr; return nullptr;
} }
void HexagonVectorLoopCarriedReuse::findLoopCarriedDeps() { void HexagonVectorLoopCarriedReuse::findLoopCarriedDeps() {
BasicBlock *BB = CurLoop->getHeader(); BasicBlock *BB = CurLoop->getHeader();
for (auto I = BB->begin(), E = BB->end(); I != E && isa<PHINode>(I); ++I) { for (auto I = BB->begin(), E = BB->end(); I != E && isa<PHINode>(I); ++I) {
@ -575,6 +616,7 @@ void HexagonVectorLoopCarriedReuse::findLoopCarriedDeps() {
dbgs() << *Dependences[i] << "\n"; dbgs() << *Dependences[i] << "\n";
}); });
} }
Pass *llvm::createHexagonVectorLoopCarriedReusePass() { Pass *llvm::createHexagonVectorLoopCarriedReusePass() {
return new HexagonVectorLoopCarriedReuse(); return new HexagonVectorLoopCarriedReuse();
} }

View File

@ -1,4 +1,4 @@
//===-- HexagonVectorPrint.cpp - Generate vector printing instructions -===// //===- HexagonVectorPrint.cpp - Generate vector printing instructions -----===//
// //
// The LLVM Compiler Infrastructure // The LLVM Compiler Infrastructure
// //
@ -13,8 +13,6 @@
// //
//===----------------------------------------------------------------------===// //===----------------------------------------------------------------------===//
#define DEBUG_TYPE "hexagon-vector-print"
#include "HexagonInstrInfo.h" #include "HexagonInstrInfo.h"
#include "HexagonSubtarget.h" #include "HexagonSubtarget.h"
#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringRef.h"
@ -31,34 +29,36 @@
#include "llvm/Support/Debug.h" #include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h" #include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetOpcodes.h"
#include <string> #include <string>
#include <vector> #include <vector>
using namespace llvm; using namespace llvm;
#define DEBUG_TYPE "hexagon-vector-print"
static cl::opt<bool> TraceHexVectorStoresOnly("trace-hex-vector-stores-only", static cl::opt<bool> TraceHexVectorStoresOnly("trace-hex-vector-stores-only",
cl::Hidden, cl::ZeroOrMore, cl::init(false), cl::Hidden, cl::ZeroOrMore, cl::init(false),
cl::desc("Enables tracing of vector stores")); cl::desc("Enables tracing of vector stores"));
namespace llvm { namespace llvm {
FunctionPass *createHexagonVectorPrint(); FunctionPass *createHexagonVectorPrint();
void initializeHexagonVectorPrintPass(PassRegistry&); void initializeHexagonVectorPrintPass(PassRegistry&);
} // end namespace llvm } // end namespace llvm
namespace { namespace {
class HexagonVectorPrint : public MachineFunctionPass { class HexagonVectorPrint : public MachineFunctionPass {
const HexagonSubtarget *QST; const HexagonSubtarget *QST = nullptr;
const HexagonInstrInfo *QII; const HexagonInstrInfo *QII = nullptr;
const HexagonRegisterInfo *QRI; const HexagonRegisterInfo *QRI = nullptr;
public: public:
static char ID; static char ID;
HexagonVectorPrint() HexagonVectorPrint() : MachineFunctionPass(ID) {
: MachineFunctionPass(ID), QST(nullptr), QII(nullptr), QRI(nullptr) {
initializeHexagonVectorPrintPass(*PassRegistry::getPassRegistry()); initializeHexagonVectorPrintPass(*PassRegistry::getPassRegistry());
} }
@ -67,10 +67,10 @@ public:
bool runOnMachineFunction(MachineFunction &Fn) override; bool runOnMachineFunction(MachineFunction &Fn) override;
}; };
char HexagonVectorPrint::ID = 0;
} // end anonymous namespace } // end anonymous namespace
char HexagonVectorPrint::ID = 0;
static bool isVecReg(unsigned Reg) { static bool isVecReg(unsigned Reg) {
return (Reg >= Hexagon::V0 && Reg <= Hexagon::V31) return (Reg >= Hexagon::V0 && Reg <= Hexagon::V31)
|| (Reg >= Hexagon::W0 && Reg <= Hexagon::W15) || (Reg >= Hexagon::W0 && Reg <= Hexagon::W15)
@ -97,7 +97,6 @@ static void addAsmInstr(MachineBasicBlock *MBB, unsigned Reg,
MachineBasicBlock::instr_iterator I, MachineBasicBlock::instr_iterator I,
const DebugLoc &DL, const HexagonInstrInfo *QII, const DebugLoc &DL, const HexagonInstrInfo *QII,
MachineFunction &Fn) { MachineFunction &Fn) {
std::string VDescStr = ".long 0x1dffe0" + getStringReg(Reg); std::string VDescStr = ".long 0x1dffe0" + getStringReg(Reg);
const char *cstr = Fn.createExternalSymbolName(VDescStr); const char *cstr = Fn.createExternalSymbolName(VDescStr);
unsigned ExtraInfo = InlineAsm::Extra_HasSideEffects; unsigned ExtraInfo = InlineAsm::Extra_HasSideEffects;