[Hexagon] Fix some Clang-tidy modernize and Include What You Use warnings; other minor fixes (NFC).
llvm-svn: 314467
This commit is contained in:
parent
4664d77316
commit
3b87336a0c
|
@ -7,8 +7,6 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "hbr"
|
||||
|
||||
#include "HexagonBlockRanges.h"
|
||||
#include "HexagonInstrInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
|
@ -17,6 +15,7 @@
|
|||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/MC/MCRegisterInfo.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
|
@ -31,6 +30,8 @@
|
|||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "hbr"
|
||||
|
||||
bool HexagonBlockRanges::IndexRange::overlaps(const IndexRange &A) const {
|
||||
// If A contains start(), or "this" contains A.start(), then overlap.
|
||||
IndexType S = start(), E = end(), AS = A.start(), AE = A.end();
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--- HexagonBlockRanges.h -----------------------------------*- C++ -*-===//
|
||||
//===- HexagonBlockRanges.h -------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -6,11 +6,11 @@
|
|||
// 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/CodeGen/MachineBasicBlock.h"
|
||||
#include <cassert>
|
||||
#include <map>
|
||||
#include <set>
|
||||
|
@ -23,6 +23,7 @@ class HexagonSubtarget;
|
|||
class MachineBasicBlock;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MachineRegisterInfo;
|
||||
class raw_ostream;
|
||||
class TargetInstrInfo;
|
||||
class TargetRegisterInfo;
|
||||
|
@ -32,11 +33,12 @@ struct HexagonBlockRanges {
|
|||
|
||||
struct RegisterRef {
|
||||
unsigned Reg, Sub;
|
||||
|
||||
bool operator<(RegisterRef R) const {
|
||||
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
|
||||
// of an instruction within a basic block.
|
||||
|
@ -49,7 +51,7 @@ struct HexagonBlockRanges {
|
|||
First = 11 // 10th + 1st
|
||||
};
|
||||
|
||||
IndexType() : Index(None) {}
|
||||
IndexType() {}
|
||||
IndexType(unsigned Idx) : Index(Idx) {}
|
||||
|
||||
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;
|
||||
|
||||
unsigned Index;
|
||||
unsigned Index = None;
|
||||
};
|
||||
|
||||
// A range of indices, essentially a representation of a live range.
|
||||
|
@ -138,7 +140,8 @@ struct HexagonBlockRanges {
|
|||
std::map<IndexType,MachineInstr*> Map;
|
||||
};
|
||||
|
||||
typedef std::map<RegisterRef,RangeList> RegToRangeMap;
|
||||
using RegToRangeMap = std::map<RegisterRef, RangeList>;
|
||||
|
||||
RegToRangeMap computeLiveMap(InstrIndexMap &IndexMap);
|
||||
RegToRangeMap computeDeadMap(InstrIndexMap &IndexMap, RegToRangeMap &LiveMap);
|
||||
static RegisterSet expandToSubRegs(RegisterRef R,
|
||||
|
@ -241,4 +244,4 @@ raw_ostream &operator<< (raw_ostream &OS,
|
|||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // HEXAGON_BLOCK_RANGES_H
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONBLOCKRANGES_H
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//===-- HexagonCFGOptimizer.cpp - CFG optimizations -----------------------===//
|
||||
//===- HexagonCFGOptimizer.cpp - CFG optimizations ------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
|
@ -7,53 +8,54 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonMachineFunctionInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "HexagonTargetMachine.h"
|
||||
#include "llvm/CodeGen/MachineDominators.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineLoopInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <cassert>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "hexagon_cfg"
|
||||
|
||||
namespace llvm {
|
||||
FunctionPass *createHexagonCFGOptimizer();
|
||||
void initializeHexagonCFGOptimizerPass(PassRegistry&);
|
||||
}
|
||||
|
||||
FunctionPass *createHexagonCFGOptimizer();
|
||||
void initializeHexagonCFGOptimizerPass(PassRegistry&);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
namespace {
|
||||
|
||||
class HexagonCFGOptimizer : public MachineFunctionPass {
|
||||
|
||||
private:
|
||||
void InvertAndChangeJumpTarget(MachineInstr &, MachineBasicBlock *);
|
||||
bool isOnFallThroughPath(MachineBasicBlock *MBB);
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
HexagonCFGOptimizer() : MachineFunctionPass(ID) {
|
||||
initializeHexagonCFGOptimizerPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
StringRef getPassName() const override { return "Hexagon CFG Optimizer"; }
|
||||
bool runOnMachineFunction(MachineFunction &Fn) override;
|
||||
|
||||
MachineFunctionProperties getRequiredProperties() const override {
|
||||
return MachineFunctionProperties().set(
|
||||
MachineFunctionProperties::Property::NoVRegs);
|
||||
}
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char HexagonCFGOptimizer::ID = 0;
|
||||
|
||||
|
@ -72,7 +74,6 @@ static bool IsConditionalBranch(int Opc) {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool IsUnconditionalJump(int Opc) {
|
||||
return (Opc == Hexagon::J2_jump);
|
||||
}
|
||||
|
@ -86,19 +87,15 @@ void HexagonCFGOptimizer::InvertAndChangeJumpTarget(
|
|||
case Hexagon::J2_jumpt:
|
||||
NewOpcode = Hexagon::J2_jumpf;
|
||||
break;
|
||||
|
||||
case Hexagon::J2_jumpf:
|
||||
NewOpcode = Hexagon::J2_jumpt;
|
||||
break;
|
||||
|
||||
case Hexagon::J2_jumptnewpt:
|
||||
NewOpcode = Hexagon::J2_jumpfnewpt;
|
||||
break;
|
||||
|
||||
case Hexagon::J2_jumpfnewpt:
|
||||
NewOpcode = Hexagon::J2_jumptnewpt;
|
||||
break;
|
||||
|
||||
default:
|
||||
llvm_unreachable("Cannot handle this case");
|
||||
}
|
||||
|
@ -131,8 +128,6 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
|
|||
MachineInstr &MI = *MII;
|
||||
int Opc = MI.getOpcode();
|
||||
if (IsConditionalBranch(Opc)) {
|
||||
|
||||
//
|
||||
// (Case 1) Transform the code if the following condition occurs:
|
||||
// BB1: if (p0) jump BB3
|
||||
// ...falls-through to BB2 ...
|
||||
|
@ -160,7 +155,6 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
|
|||
// Remove BB2
|
||||
// BB3: ...
|
||||
// BB4: ...
|
||||
//
|
||||
unsigned NumSuccs = MBB->succ_size();
|
||||
MachineBasicBlock::succ_iterator SI = MBB->succ_begin();
|
||||
MachineBasicBlock* FirstSucc = *SI;
|
||||
|
@ -200,7 +194,7 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
|
|||
// Check if the layout successor of BB2 is BB3.
|
||||
bool case1 = LayoutSucc->isLayoutSuccessor(JumpAroundTarget);
|
||||
bool case2 = JumpAroundTarget->isSuccessor(UncondTarget) &&
|
||||
JumpAroundTarget->size() >= 1 &&
|
||||
!JumpAroundTarget->empty() &&
|
||||
IsUnconditionalJump(JumpAroundTarget->back().getOpcode()) &&
|
||||
JumpAroundTarget->pred_size() == 1 &&
|
||||
JumpAroundTarget->succ_size() == 1;
|
||||
|
@ -223,11 +217,9 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
|
|||
UncondTarget->moveAfter(JumpAroundTarget);
|
||||
}
|
||||
|
||||
//
|
||||
// Correct live-in information. Is used by post-RA scheduler
|
||||
// The live-in to LayoutSucc is now all values live-in to
|
||||
// JumpAroundTarget.
|
||||
//
|
||||
std::vector<MachineBasicBlock::RegisterMaskPair> OrigLiveIn(
|
||||
LayoutSucc->livein_begin(), LayoutSucc->livein_end());
|
||||
std::vector<MachineBasicBlock::RegisterMaskPair> NewLiveIn(
|
||||
|
@ -245,8 +237,6 @@ bool HexagonCFGOptimizer::runOnMachineFunction(MachineFunction &Fn) {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// Public Constructor Functions
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--- HexagonGenExtract.cpp --------------------------------------------===//
|
||||
//===- HexagonGenExtract.cpp ----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -8,7 +8,7 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "llvm/ADT/APInt.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/ADT/GraphTraits.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/CFG.h"
|
||||
#include "llvm/IR/Constants.h"
|
||||
|
@ -47,8 +47,8 @@ static cl::opt<bool> NeedAnd("extract-needand", cl::init(true), cl::Hidden,
|
|||
|
||||
namespace llvm {
|
||||
|
||||
void initializeHexagonGenExtractPass(PassRegistry&);
|
||||
FunctionPass *createHexagonGenExtract();
|
||||
void initializeHexagonGenExtractPass(PassRegistry&);
|
||||
FunctionPass *createHexagonGenExtract();
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -58,7 +58,7 @@ namespace {
|
|||
public:
|
||||
static char ID;
|
||||
|
||||
HexagonGenExtract() : FunctionPass(ID), ExtractCount(0) {
|
||||
HexagonGenExtract() : FunctionPass(ID) {
|
||||
initializeHexagonGenExtractPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
|
@ -78,14 +78,14 @@ namespace {
|
|||
bool visitBlock(BasicBlock *B);
|
||||
bool convert(Instruction *In);
|
||||
|
||||
unsigned ExtractCount;
|
||||
unsigned ExtractCount = 0;
|
||||
DominatorTree *DT;
|
||||
};
|
||||
|
||||
char HexagonGenExtract::ID = 0;
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char HexagonGenExtract::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(HexagonGenExtract, "hextract", "Hexagon generate "
|
||||
"\"extract\" instructions", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass)
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- HexagonInstrInfo.cpp - Hexagon Instruction Information ------------===//
|
||||
//===- HexagonInstrInfo.cpp - Hexagon Instruction Information -------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -13,9 +13,11 @@
|
|||
|
||||
#include "HexagonInstrInfo.h"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonFrameLowering.h"
|
||||
#include "HexagonHazardRecognizer.h"
|
||||
#include "HexagonRegisterInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
@ -32,7 +34,9 @@
|
|||
#include "llvm/CodeGen/MachineMemOperand.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/MachineValueType.h"
|
||||
#include "llvm/CodeGen/ScheduleDAG.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/MC/MCAsmInfo.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/MC/MCInstrItineraries.h"
|
||||
|
@ -44,12 +48,17 @@
|
|||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.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 <cassert>
|
||||
#include <cctype>
|
||||
#include <cstdint>
|
||||
#include <cstring>
|
||||
#include <iterator>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
|
@ -91,9 +100,7 @@ static cl::opt<bool> UseDFAHazardRec("dfa-hazard-rec",
|
|||
cl::init(true), cl::Hidden, cl::ZeroOrMore,
|
||||
cl::desc("Use the DFA based hazard recognizer."));
|
||||
|
||||
///
|
||||
/// Constants for Hexagon instructions.
|
||||
///
|
||||
const int Hexagon_MEMW_OFFSET_MAX = 4095;
|
||||
const int Hexagon_MEMW_OFFSET_MIN = -4096;
|
||||
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[1] = R
|
||||
/// Cond[2] = Imm
|
||||
///
|
||||
bool HexagonInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
|
||||
MachineBasicBlock *&TBB,
|
||||
MachineBasicBlock *&FBB,
|
||||
|
@ -576,7 +582,7 @@ unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB,
|
|||
SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
|
||||
MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
|
||||
VisitedBBs);
|
||||
assert(Loop != 0 && "Inserting an ENDLOOP without a LOOP");
|
||||
assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
|
||||
Loop->getOperand(0).setMBB(TBB);
|
||||
// Add the ENDLOOP after the finding the LOOP0.
|
||||
BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
|
||||
|
@ -617,7 +623,7 @@ unsigned HexagonInstrInfo::insertBranch(MachineBasicBlock &MBB,
|
|||
SmallPtrSet<MachineBasicBlock *, 8> VisitedBBs;
|
||||
MachineInstr *Loop = findLoopInstr(TBB, EndLoopOp, Cond[1].getMBB(),
|
||||
VisitedBBs);
|
||||
assert(Loop != 0 && "Inserting an ENDLOOP without a LOOP");
|
||||
assert(Loop != nullptr && "Inserting an ENDLOOP without a LOOP");
|
||||
Loop->getOperand(0).setMBB(TBB);
|
||||
// Add the ENDLOOP after the finding the LOOP0.
|
||||
BuildMI(&MBB, DL, get(EndLoopOp)).addMBB(TBB);
|
||||
|
@ -1580,7 +1586,6 @@ unsigned HexagonInstrInfo::getInstrLatency(const InstrItineraryData *ItinData,
|
|||
return getInstrTimingClassLatency(ItinData, MI);
|
||||
}
|
||||
|
||||
|
||||
DFAPacketizer *HexagonInstrInfo::CreateTargetScheduleState(
|
||||
const TargetSubtargetInfo &STI) const {
|
||||
const InstrItineraryData *II = STI.getInstrItineraryData();
|
||||
|
@ -1672,6 +1677,7 @@ HexagonInstrInfo::decomposeMachineOperandsTargetFlags(unsigned TF) const {
|
|||
ArrayRef<std::pair<unsigned, const char*>>
|
||||
HexagonInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
|
||||
using namespace HexagonII;
|
||||
|
||||
static const std::pair<unsigned, const char*> Flags[] = {
|
||||
{MO_PCREL, "hexagon-pcrel"},
|
||||
{MO_GOT, "hexagon-got"},
|
||||
|
@ -1690,6 +1696,7 @@ HexagonInstrInfo::getSerializableDirectMachineOperandTargetFlags() const {
|
|||
ArrayRef<std::pair<unsigned, const char*>>
|
||||
HexagonInstrInfo::getSerializableBitmaskMachineOperandTargetFlags() const {
|
||||
using namespace HexagonII;
|
||||
|
||||
static const std::pair<unsigned, const char*> Flags[] = {
|
||||
{HMOTF_ConstExtended, "hexagon-ext"}
|
||||
};
|
||||
|
@ -1794,13 +1801,13 @@ bool HexagonInstrInfo::isConstExtended(const MachineInstr &MI) const {
|
|||
|
||||
bool HexagonInstrInfo::isDeallocRet(const MachineInstr &MI) const {
|
||||
switch (MI.getOpcode()) {
|
||||
case Hexagon::L4_return :
|
||||
case Hexagon::L4_return_t :
|
||||
case Hexagon::L4_return_f :
|
||||
case Hexagon::L4_return_tnew_pnt :
|
||||
case Hexagon::L4_return_fnew_pnt :
|
||||
case Hexagon::L4_return_tnew_pt :
|
||||
case Hexagon::L4_return_fnew_pt :
|
||||
case Hexagon::L4_return:
|
||||
case Hexagon::L4_return_t:
|
||||
case Hexagon::L4_return_f:
|
||||
case Hexagon::L4_return_tnew_pnt:
|
||||
case Hexagon::L4_return_fnew_pnt:
|
||||
case Hexagon::L4_return_tnew_pt:
|
||||
case Hexagon::L4_return_fnew_pt:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1950,10 +1957,10 @@ bool HexagonInstrInfo::isHVXMemWithAIndirect(const MachineInstr &I,
|
|||
|
||||
bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const {
|
||||
switch (MI.getOpcode()) {
|
||||
case Hexagon::J2_callr :
|
||||
case Hexagon::J2_callrf :
|
||||
case Hexagon::J2_callrt :
|
||||
case Hexagon::PS_call_nr :
|
||||
case Hexagon::J2_callr:
|
||||
case Hexagon::J2_callrf:
|
||||
case Hexagon::J2_callrt:
|
||||
case Hexagon::PS_call_nr:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1961,13 +1968,13 @@ bool HexagonInstrInfo::isIndirectCall(const MachineInstr &MI) const {
|
|||
|
||||
bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const {
|
||||
switch (MI.getOpcode()) {
|
||||
case Hexagon::L4_return :
|
||||
case Hexagon::L4_return_t :
|
||||
case Hexagon::L4_return_f :
|
||||
case Hexagon::L4_return_fnew_pnt :
|
||||
case Hexagon::L4_return_fnew_pt :
|
||||
case Hexagon::L4_return_tnew_pnt :
|
||||
case Hexagon::L4_return_tnew_pt :
|
||||
case Hexagon::L4_return:
|
||||
case Hexagon::L4_return_t:
|
||||
case Hexagon::L4_return_f:
|
||||
case Hexagon::L4_return_fnew_pnt:
|
||||
case Hexagon::L4_return_fnew_pt:
|
||||
case Hexagon::L4_return_tnew_pnt:
|
||||
case Hexagon::L4_return_tnew_pt:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -1975,13 +1982,13 @@ bool HexagonInstrInfo::isIndirectL4Return(const MachineInstr &MI) const {
|
|||
|
||||
bool HexagonInstrInfo::isJumpR(const MachineInstr &MI) const {
|
||||
switch (MI.getOpcode()) {
|
||||
case Hexagon::J2_jumpr :
|
||||
case Hexagon::J2_jumprt :
|
||||
case Hexagon::J2_jumprf :
|
||||
case Hexagon::J2_jumprtnewpt :
|
||||
case Hexagon::J2_jumprfnewpt :
|
||||
case Hexagon::J2_jumprtnew :
|
||||
case Hexagon::J2_jumprfnew :
|
||||
case Hexagon::J2_jumpr:
|
||||
case Hexagon::J2_jumprt:
|
||||
case Hexagon::J2_jumprf:
|
||||
case Hexagon::J2_jumprtnewpt:
|
||||
case Hexagon::J2_jumprfnewpt:
|
||||
case Hexagon::J2_jumprtnew:
|
||||
case Hexagon::J2_jumprfnew:
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -2089,24 +2096,24 @@ bool HexagonInstrInfo::isLoopN(const MachineInstr &MI) const {
|
|||
bool HexagonInstrInfo::isMemOp(const MachineInstr &MI) const {
|
||||
switch (MI.getOpcode()) {
|
||||
default: return false;
|
||||
case Hexagon::L4_iadd_memopw_io :
|
||||
case Hexagon::L4_isub_memopw_io :
|
||||
case Hexagon::L4_add_memopw_io :
|
||||
case Hexagon::L4_sub_memopw_io :
|
||||
case Hexagon::L4_and_memopw_io :
|
||||
case Hexagon::L4_or_memopw_io :
|
||||
case Hexagon::L4_iadd_memoph_io :
|
||||
case Hexagon::L4_isub_memoph_io :
|
||||
case Hexagon::L4_add_memoph_io :
|
||||
case Hexagon::L4_sub_memoph_io :
|
||||
case Hexagon::L4_and_memoph_io :
|
||||
case Hexagon::L4_or_memoph_io :
|
||||
case Hexagon::L4_iadd_memopb_io :
|
||||
case Hexagon::L4_isub_memopb_io :
|
||||
case Hexagon::L4_add_memopb_io :
|
||||
case Hexagon::L4_sub_memopb_io :
|
||||
case Hexagon::L4_and_memopb_io :
|
||||
case Hexagon::L4_or_memopb_io :
|
||||
case Hexagon::L4_iadd_memopw_io:
|
||||
case Hexagon::L4_isub_memopw_io:
|
||||
case Hexagon::L4_add_memopw_io:
|
||||
case Hexagon::L4_sub_memopw_io:
|
||||
case Hexagon::L4_and_memopw_io:
|
||||
case Hexagon::L4_or_memopw_io:
|
||||
case Hexagon::L4_iadd_memoph_io:
|
||||
case Hexagon::L4_isub_memoph_io:
|
||||
case Hexagon::L4_add_memoph_io:
|
||||
case Hexagon::L4_sub_memoph_io:
|
||||
case Hexagon::L4_and_memoph_io:
|
||||
case Hexagon::L4_or_memoph_io:
|
||||
case Hexagon::L4_iadd_memopb_io:
|
||||
case Hexagon::L4_isub_memopb_io:
|
||||
case Hexagon::L4_add_memopb_io:
|
||||
case Hexagon::L4_sub_memopb_io:
|
||||
case Hexagon::L4_and_memopb_io:
|
||||
case Hexagon::L4_or_memopb_io:
|
||||
case Hexagon::L4_ior_memopb_io:
|
||||
case Hexagon::L4_ior_memoph_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 {
|
||||
switch (MI.getOpcode()) {
|
||||
case Hexagon::STriw_pred :
|
||||
case Hexagon::LDriw_pred :
|
||||
case Hexagon::STriw_pred:
|
||||
case Hexagon::LDriw_pred:
|
||||
return true;
|
||||
default:
|
||||
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.
|
||||
//
|
||||
bool HexagonInstrInfo::isValidAutoIncImm(const EVT VT, int Offset) const {
|
||||
int Size = VT.getSizeInBits() / 8;
|
||||
if (Offset % Size != 0)
|
||||
|
@ -2469,28 +2475,28 @@ bool HexagonInstrInfo::isValidOffset(unsigned Opcode, int Offset,
|
|||
return (Offset >= Hexagon_ADDI_OFFSET_MIN) &&
|
||||
(Offset <= Hexagon_ADDI_OFFSET_MAX);
|
||||
|
||||
case Hexagon::L4_iadd_memopw_io :
|
||||
case Hexagon::L4_isub_memopw_io :
|
||||
case Hexagon::L4_add_memopw_io :
|
||||
case Hexagon::L4_sub_memopw_io :
|
||||
case Hexagon::L4_and_memopw_io :
|
||||
case Hexagon::L4_or_memopw_io :
|
||||
case Hexagon::L4_iadd_memopw_io:
|
||||
case Hexagon::L4_isub_memopw_io:
|
||||
case Hexagon::L4_add_memopw_io:
|
||||
case Hexagon::L4_sub_memopw_io:
|
||||
case Hexagon::L4_and_memopw_io:
|
||||
case Hexagon::L4_or_memopw_io:
|
||||
return (0 <= Offset && Offset <= 255);
|
||||
|
||||
case Hexagon::L4_iadd_memoph_io :
|
||||
case Hexagon::L4_isub_memoph_io :
|
||||
case Hexagon::L4_add_memoph_io :
|
||||
case Hexagon::L4_sub_memoph_io :
|
||||
case Hexagon::L4_and_memoph_io :
|
||||
case Hexagon::L4_or_memoph_io :
|
||||
case Hexagon::L4_iadd_memoph_io:
|
||||
case Hexagon::L4_isub_memoph_io:
|
||||
case Hexagon::L4_add_memoph_io:
|
||||
case Hexagon::L4_sub_memoph_io:
|
||||
case Hexagon::L4_and_memoph_io:
|
||||
case Hexagon::L4_or_memoph_io:
|
||||
return (0 <= Offset && Offset <= 127);
|
||||
|
||||
case Hexagon::L4_iadd_memopb_io :
|
||||
case Hexagon::L4_isub_memopb_io :
|
||||
case Hexagon::L4_add_memopb_io :
|
||||
case Hexagon::L4_sub_memopb_io :
|
||||
case Hexagon::L4_and_memopb_io :
|
||||
case Hexagon::L4_or_memopb_io :
|
||||
case Hexagon::L4_iadd_memopb_io:
|
||||
case Hexagon::L4_isub_memopb_io:
|
||||
case Hexagon::L4_add_memopb_io:
|
||||
case Hexagon::L4_sub_memopb_io:
|
||||
case Hexagon::L4_and_memopb_io:
|
||||
case Hexagon::L4_or_memopb_io:
|
||||
return (0 <= Offset && Offset <= 63);
|
||||
|
||||
// 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.
|
||||
|
||||
switch (getAddrMode(MI)) {
|
||||
case HexagonII::Absolute :
|
||||
case HexagonII::Absolute:
|
||||
// Load/store with absolute addressing mode can be converted into
|
||||
// base+offset mode.
|
||||
NonExtOpcode = Hexagon::getBaseWithImmOffset(MI.getOpcode());
|
||||
break;
|
||||
case HexagonII::BaseImmOffset :
|
||||
case HexagonII::BaseImmOffset:
|
||||
// Load/store with base+offset addressing mode can be converted into
|
||||
// base+register offset addressing mode. However left shift operand should
|
||||
// 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_PIC:
|
||||
return HexagonII::HCG_C;
|
||||
break;
|
||||
}
|
||||
|
||||
return HexagonII::HCG_None;
|
||||
|
@ -3148,7 +3153,6 @@ int HexagonInstrInfo::getNonDotCurOp(const MachineInstr &MI) const {
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// The diagram below shows the steps involved in the conversion of a predicated
|
||||
// store instruction to its .new predicated new-value form.
|
||||
//
|
||||
|
@ -3238,8 +3242,8 @@ int HexagonInstrInfo::getDotNewOp(const MachineInstr &MI) const {
|
|||
|
||||
switch (MI.getOpcode()) {
|
||||
default:
|
||||
llvm::report_fatal_error(std::string("Unknown .new type: ") +
|
||||
std::to_string(MI.getOpcode()).c_str());
|
||||
report_fatal_error(std::string("Unknown .new type: ") +
|
||||
std::to_string(MI.getOpcode()));
|
||||
case Hexagon::S4_storerb_ur:
|
||||
return Hexagon::S4_storerbnew_ur;
|
||||
|
||||
|
@ -3535,12 +3539,12 @@ HexagonII::SubInstructionGroup HexagonInstrInfo::getDuplexCandidateGroup(
|
|||
(Hexagon::IntRegsRegClass.contains(DstReg) && (Hexagon::R31 == DstReg)))
|
||||
return HexagonII::HSIG_L2;
|
||||
break;
|
||||
case Hexagon::L4_return_t :
|
||||
case Hexagon::L4_return_f :
|
||||
case Hexagon::L4_return_tnew_pnt :
|
||||
case Hexagon::L4_return_fnew_pnt :
|
||||
case Hexagon::L4_return_tnew_pt :
|
||||
case Hexagon::L4_return_fnew_pt :
|
||||
case Hexagon::L4_return_t:
|
||||
case Hexagon::L4_return_f:
|
||||
case Hexagon::L4_return_tnew_pnt:
|
||||
case Hexagon::L4_return_fnew_pnt:
|
||||
case Hexagon::L4_return_tnew_pt:
|
||||
case Hexagon::L4_return_fnew_pt:
|
||||
// [if ([!]p0[.new])] dealloc_return
|
||||
SrcReg = MI.getOperand(0).getReg();
|
||||
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 {
|
||||
using namespace HexagonII;
|
||||
|
||||
const uint64_t F = MI.getDesc().TSFlags;
|
||||
unsigned S = (F >> MemAccessSizePos) & MemAccesSizeMask;
|
||||
unsigned Size = getMemAccessSizeInBytes(MemAccessSize(S));
|
||||
|
@ -3912,9 +3917,9 @@ short HexagonInstrInfo::getNonExtOpcode(const MachineInstr &MI) const {
|
|||
if (MI.getDesc().mayLoad() || MI.getDesc().mayStore()) {
|
||||
// Check addressing mode and retrieve non-ext equivalent instruction.
|
||||
switch (getAddrMode(MI)) {
|
||||
case HexagonII::Absolute :
|
||||
case HexagonII::Absolute:
|
||||
return Hexagon::getBaseWithImmOffset(MI.getOpcode());
|
||||
case HexagonII::BaseImmOffset :
|
||||
case HexagonII::BaseImmOffset:
|
||||
return Hexagon::getBaseWithRegOffset(MI.getOpcode());
|
||||
case HexagonII::BaseLongOffset:
|
||||
return Hexagon::getRegShlForm(MI.getOpcode());
|
||||
|
|
|
@ -18,8 +18,8 @@
|
|||
#include "llvm/ADT/ArrayRef.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
|
||||
#include "llvm/CodeGen/MachineValueType.h"
|
||||
#include "llvm/CodeGen/ValueTypes.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include <cstdint>
|
||||
#include <vector>
|
||||
|
@ -29,9 +29,12 @@
|
|||
|
||||
namespace llvm {
|
||||
|
||||
struct EVT;
|
||||
class HexagonSubtarget;
|
||||
class HexagonRegisterInfo;
|
||||
class MachineBranchProbabilityInfo;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MachineOperand;
|
||||
class TargetRegisterInfo;
|
||||
|
||||
class HexagonInstrInfo : public HexagonGenInstrInfo {
|
||||
virtual void anchor();
|
||||
|
@ -40,7 +43,6 @@ public:
|
|||
explicit HexagonInstrInfo(HexagonSubtarget &ST);
|
||||
|
||||
/// TargetInstrInfo overrides.
|
||||
///
|
||||
|
||||
/// If the specified machine instruction is a direct
|
||||
/// 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
|
||||
/// block (e.g. delete instructions after the unconditional branch).
|
||||
///
|
||||
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
|
||||
MachineBasicBlock *&FBB,
|
||||
SmallVectorImpl<MachineOperand> &Cond,
|
||||
|
@ -249,7 +250,7 @@ public:
|
|||
/// Allocate and return a hazard recognizer to use for this target when
|
||||
/// scheduling the machine instructions after register allocation.
|
||||
ScheduleHazardRecognizer*
|
||||
CreateTargetPostRAHazardRecognizer(const InstrItineraryData*,
|
||||
CreateTargetPostRAHazardRecognizer(const InstrItineraryData *II,
|
||||
const ScheduleDAG *DAG) const override;
|
||||
|
||||
/// For a comparison instruction, return the source registers
|
||||
|
@ -323,7 +324,6 @@ public:
|
|||
bool isTailCall(const MachineInstr &MI) const override;
|
||||
|
||||
/// HexagonInstrInfo specifics.
|
||||
///
|
||||
|
||||
unsigned createVR(MachineFunction* MF, MVT VT) const;
|
||||
|
||||
|
|
|
@ -13,13 +13,37 @@
|
|||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "HexagonMachineScheduler.h"
|
||||
#include "HexagonInstrInfo.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/RegisterPressure.h"
|
||||
#include "llvm/CodeGen/ScheduleDAG.h"
|
||||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
||||
#include "llvm/CodeGen/TargetSchedule.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 <limits>
|
||||
#include <memory>
|
||||
#include <sstream>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "machine-scheduler"
|
||||
|
||||
static cl::opt<bool> IgnoreBBRegPressure("ignore-bb-reg-pressure",
|
||||
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,
|
||||
cl::ZeroOrMore, cl::init(true));
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "machine-scheduler"
|
||||
|
||||
/// Save the last formed packet
|
||||
void VLIWResourceModel::savePacket() {
|
||||
OldPacket = Packet;
|
||||
|
@ -246,7 +266,7 @@ void ConvergingVLIWScheduler::initialize(ScheduleDAGMI *dag) {
|
|||
Top.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");
|
||||
}
|
||||
|
||||
|
@ -328,7 +348,8 @@ void ConvergingVLIWScheduler::VLIWSchedBoundary::bumpCycle() {
|
|||
unsigned Width = SchedModel->getIssueWidth();
|
||||
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);
|
||||
|
||||
if (!HazardRec->isEnabled()) {
|
||||
|
@ -383,7 +404,7 @@ void ConvergingVLIWScheduler::VLIWSchedBoundary::bumpNode(SUnit *SU) {
|
|||
void ConvergingVLIWScheduler::VLIWSchedBoundary::releasePending() {
|
||||
// If the available queue is empty, it is safe to reset MinReadyCycle.
|
||||
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
|
||||
// so, add them to the available queue.
|
||||
|
@ -883,7 +904,7 @@ SUnit *ConvergingVLIWScheduler::pickNode(bool &IsTopNode) {
|
|||
return nullptr;
|
||||
}
|
||||
SUnit *SU;
|
||||
if (llvm::ForceTopDown) {
|
||||
if (ForceTopDown) {
|
||||
SU = Top.pickOnlyChoice();
|
||||
if (!SU) {
|
||||
SchedCandidate TopCand;
|
||||
|
@ -894,7 +915,7 @@ SUnit *ConvergingVLIWScheduler::pickNode(bool &IsTopNode) {
|
|||
SU = TopCand.SU;
|
||||
}
|
||||
IsTopNode = true;
|
||||
} else if (llvm::ForceBottomUp) {
|
||||
} else if (ForceBottomUp) {
|
||||
SU = Bot.pickOnlyChoice();
|
||||
if (!SU) {
|
||||
SchedCandidate BotCand;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- HexagonMachineScheduler.h - Custom Hexagon MI scheduler. ----===//
|
||||
//===- HexagonMachineScheduler.h - Custom Hexagon MI scheduler --*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -14,25 +14,25 @@
|
|||
#ifndef LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H
|
||||
#define LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H
|
||||
|
||||
#include "llvm/ADT/PriorityQueue.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/ADT/Twine.h"
|
||||
#include "llvm/CodeGen/DFAPacketizer.h"
|
||||
#include "llvm/CodeGen/MachineScheduler.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/RegisterClassInfo.h"
|
||||
#include "llvm/CodeGen/RegisterPressure.h"
|
||||
#include "llvm/CodeGen/ResourcePriorityQueue.h"
|
||||
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
|
||||
#include "llvm/CodeGen/ScheduleHazardRecognizer.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/CodeGen/TargetSchedule.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
|
||||
using namespace llvm;
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <algorithm>
|
||||
#include <cassert>
|
||||
#include <limits>
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class SUnit;
|
||||
|
||||
class VLIWResourceModel {
|
||||
/// ResourcesModel - Represents VLIW state.
|
||||
/// Not limited to VLIW targets per se, but assumes
|
||||
|
@ -43,18 +43,17 @@ class VLIWResourceModel {
|
|||
|
||||
/// Local packet/bundle model. Purely
|
||||
/// internal to the MI schedulre at the time.
|
||||
std::vector<SUnit*> Packet;
|
||||
std::vector<SUnit *> Packet;
|
||||
|
||||
/// Total packets created.
|
||||
unsigned TotalPackets;
|
||||
unsigned TotalPackets = 0;
|
||||
|
||||
public:
|
||||
/// Save the last formed packet.
|
||||
std::vector<SUnit*> OldPacket;
|
||||
std::vector<SUnit *> OldPacket;
|
||||
|
||||
public:
|
||||
VLIWResourceModel(const TargetSubtargetInfo &STI, const TargetSchedModel *SM)
|
||||
: SchedModel(SM), TotalPackets(0) {
|
||||
: SchedModel(SM) {
|
||||
ResourcesModel = STI.getInstrInfo()->CreateTargetScheduleState(STI);
|
||||
|
||||
// This hard requirement could be relaxed,
|
||||
|
@ -89,7 +88,6 @@ public:
|
|||
bool reserveResources(SUnit *SU);
|
||||
void savePacket();
|
||||
unsigned getTotalPackets() const { return TotalPackets; }
|
||||
|
||||
bool isInPacket(SUnit *SU) const { return is_contained(Packet, SU); }
|
||||
};
|
||||
|
||||
|
@ -114,20 +112,19 @@ public:
|
|||
/// ConvergingVLIWScheduler shrinks the unscheduled zone using heuristics
|
||||
/// to balance the schedule.
|
||||
class ConvergingVLIWScheduler : public MachineSchedStrategy {
|
||||
|
||||
/// Store the state used by ConvergingVLIWScheduler heuristics, required
|
||||
/// for the lifetime of one invocation of pickNode().
|
||||
struct SchedCandidate {
|
||||
// The best SUnit candidate.
|
||||
SUnit *SU;
|
||||
SUnit *SU = nullptr;
|
||||
|
||||
// Register pressure values for the best candidate.
|
||||
RegPressureDelta RPDelta;
|
||||
|
||||
// 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.
|
||||
enum CandResult {
|
||||
|
@ -138,33 +135,30 @@ class ConvergingVLIWScheduler : public MachineSchedStrategy {
|
|||
/// current cycle in whichever direction at has moved, and maintains the state
|
||||
/// of "hazards" and other interlocks at the current cycle.
|
||||
struct VLIWSchedBoundary {
|
||||
VLIWMachineScheduler *DAG;
|
||||
const TargetSchedModel *SchedModel;
|
||||
VLIWMachineScheduler *DAG = nullptr;
|
||||
const TargetSchedModel *SchedModel = nullptr;
|
||||
|
||||
ReadyQueue Available;
|
||||
ReadyQueue Pending;
|
||||
bool CheckPending;
|
||||
bool CheckPending = false;
|
||||
|
||||
ScheduleHazardRecognizer *HazardRec;
|
||||
VLIWResourceModel *ResourceModel;
|
||||
ScheduleHazardRecognizer *HazardRec = nullptr;
|
||||
VLIWResourceModel *ResourceModel = nullptr;
|
||||
|
||||
unsigned CurrCycle;
|
||||
unsigned IssueCount;
|
||||
unsigned CurrCycle = 0;
|
||||
unsigned IssueCount = 0;
|
||||
|
||||
/// MinReadyCycle - Cycle of the soonest available instruction.
|
||||
unsigned MinReadyCycle;
|
||||
unsigned MinReadyCycle = std::numeric_limits<unsigned>::max();
|
||||
|
||||
// Remember the greatest min operand latency.
|
||||
unsigned MaxMinLatency;
|
||||
unsigned MaxMinLatency = 0;
|
||||
|
||||
/// Pending queues extend the ready queues with the same ID and the
|
||||
/// PendingFlag set.
|
||||
VLIWSchedBoundary(unsigned ID, const Twine &Name):
|
||||
DAG(nullptr), SchedModel(nullptr), Available(ID, Name+".A"),
|
||||
Pending(ID << ConvergingVLIWScheduler::LogMaxQID, Name+".P"),
|
||||
CheckPending(false), HazardRec(nullptr), ResourceModel(nullptr),
|
||||
CurrCycle(0), IssueCount(0),
|
||||
MinReadyCycle(UINT_MAX), MaxMinLatency(0) {}
|
||||
VLIWSchedBoundary(unsigned ID, const Twine &Name)
|
||||
: Available(ID, Name+".A"),
|
||||
Pending(ID << ConvergingVLIWScheduler::LogMaxQID, Name+".P") {}
|
||||
|
||||
~VLIWSchedBoundary() {
|
||||
delete ResourceModel;
|
||||
|
@ -196,8 +190,8 @@ class ConvergingVLIWScheduler : public MachineSchedStrategy {
|
|||
SUnit *pickOnlyChoice();
|
||||
};
|
||||
|
||||
VLIWMachineScheduler *DAG;
|
||||
const TargetSchedModel *SchedModel;
|
||||
VLIWMachineScheduler *DAG = nullptr;
|
||||
const TargetSchedModel *SchedModel = nullptr;
|
||||
|
||||
// State of the top and bottom scheduled instruction boundaries.
|
||||
VLIWSchedBoundary Top;
|
||||
|
@ -211,9 +205,7 @@ public:
|
|||
LogMaxQID = 2
|
||||
};
|
||||
|
||||
ConvergingVLIWScheduler()
|
||||
: DAG(nullptr), SchedModel(nullptr), Top(TopQID, "TopQ"),
|
||||
Bot(BotQID, "BotQ") {}
|
||||
ConvergingVLIWScheduler() : Top(TopQID, "TopQ"), Bot(BotQID, "BotQ") {}
|
||||
|
||||
void initialize(ScheduleDAGMI *dag) override;
|
||||
|
||||
|
@ -249,6 +241,6 @@ protected:
|
|||
#endif
|
||||
};
|
||||
|
||||
} // namespace
|
||||
} // end namespace llvm
|
||||
|
||||
#endif
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONMACHINESCHEDULER_H
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===----- HexagonNewValueJump.cpp - Hexagon Backend New Value Jump -------===//
|
||||
//===- HexagonNewValueJump.cpp - Hexagon Backend New Value Jump -----------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -19,28 +19,36 @@
|
|||
// all, it collapses compare and jump instruction into a new valu jump
|
||||
// intstructions.
|
||||
//
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonInstrInfo.h"
|
||||
#include "HexagonMachineFunctionInfo.h"
|
||||
#include "HexagonRegisterInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "HexagonTargetMachine.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/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineInstrBuilder.h"
|
||||
#include "llvm/CodeGen/MachineOperand.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
|
||||
#include "llvm/PassSupport.h"
|
||||
#include "llvm/IR/DebugLoc.h"
|
||||
#include "llvm/MC/MCInstrDesc.h"
|
||||
#include "llvm/Pass.h"
|
||||
#include "llvm/Support/BranchProbability.h"
|
||||
#include "llvm/Support/CommandLine.h"
|
||||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/MathExtras.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetInstrInfo.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOpcodes.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||
#include <cassert>
|
||||
#include <cstdint>
|
||||
#include <iterator>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "hexagon-nvj"
|
||||
|
@ -56,12 +64,14 @@ static cl::opt<bool> DisableNewValueJumps("disable-nvjump", cl::Hidden,
|
|||
cl::desc("Disable New Value Jumps"));
|
||||
|
||||
namespace llvm {
|
||||
FunctionPass *createHexagonNewValueJump();
|
||||
void initializeHexagonNewValueJumpPass(PassRegistry&);
|
||||
}
|
||||
|
||||
FunctionPass *createHexagonNewValueJump();
|
||||
void initializeHexagonNewValueJumpPass(PassRegistry&);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
namespace {
|
||||
|
||||
struct HexagonNewValueJump : public MachineFunctionPass {
|
||||
static char ID;
|
||||
|
||||
|
@ -75,6 +85,7 @@ namespace {
|
|||
StringRef getPassName() const override { return "Hexagon NewValueJump"; }
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &Fn) override;
|
||||
|
||||
MachineFunctionProperties getRequiredProperties() const override {
|
||||
return MachineFunctionProperties().set(
|
||||
MachineFunctionProperties::Property::NoVRegs);
|
||||
|
@ -90,7 +101,7 @@ namespace {
|
|||
bool isNewValueJumpCandidate(const MachineInstr &MI) const;
|
||||
};
|
||||
|
||||
} // end of anonymous namespace
|
||||
} // end anonymous namespace
|
||||
|
||||
char HexagonNewValueJump::ID = 0;
|
||||
|
||||
|
@ -100,7 +111,6 @@ INITIALIZE_PASS_DEPENDENCY(MachineBranchProbabilityInfo)
|
|||
INITIALIZE_PASS_END(HexagonNewValueJump, "hexagon-nvj",
|
||||
"Hexagon NewValueJump", false, false)
|
||||
|
||||
|
||||
// We have identified this II could be feeder to NVJ,
|
||||
// verify that it can be.
|
||||
static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
|
||||
|
@ -109,7 +119,6 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
|
|||
MachineBasicBlock::iterator end,
|
||||
MachineBasicBlock::iterator skip,
|
||||
MachineFunction &MF) {
|
||||
|
||||
// Predicated instruction can not be feeder to NVJ.
|
||||
if (QII->isPredicated(*II))
|
||||
return false;
|
||||
|
@ -144,7 +153,6 @@ static bool canBeFeederToNewValueJump(const HexagonInstrInfo *QII,
|
|||
// p0 = cmp.eq(r21, #0)
|
||||
// if (p0.new) jump:t .LBB29_45
|
||||
// and result WAR hazards if converted to New Value Jump.
|
||||
|
||||
for (unsigned i = 0; i < II->getNumOperands(); ++i) {
|
||||
if (II->getOperand(i).isReg() &&
|
||||
(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.
|
||||
static bool commonChecksToProhibitNewValueJump(bool afterRA,
|
||||
MachineBasicBlock::iterator MII) {
|
||||
|
||||
// If store in path, bail out.
|
||||
if (MII->mayStore())
|
||||
return false;
|
||||
|
@ -216,7 +223,6 @@ static bool canCompareBeNewValueJump(const HexagonInstrInfo *QII,
|
|||
bool optLocation,
|
||||
MachineBasicBlock::iterator end,
|
||||
MachineFunction &MF) {
|
||||
|
||||
MachineInstr &MI = *II;
|
||||
|
||||
// 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) {
|
||||
|
||||
DEBUG(dbgs() << "********** Hexagon New Value Jump **********\n"
|
||||
<< "********** Function: " << MF.getName() << "\n");
|
||||
|
||||
|
@ -536,10 +540,8 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
|
|||
|
||||
if (foundJump && !foundCompare && MI.getOperand(0).isReg() &&
|
||||
MI.getOperand(0).getReg() == predReg) {
|
||||
|
||||
// Not all compares can be new value compare. Arch Spec: 7.6.1.1
|
||||
if (isNewValueJumpCandidate(MI)) {
|
||||
|
||||
assert(
|
||||
(MI.getDesc().isCompare()) &&
|
||||
"Only compare instruction can be collapsed into New Value Jump");
|
||||
|
@ -566,7 +568,6 @@ bool HexagonNewValueJump::runOnMachineFunction(MachineFunction &MF) {
|
|||
}
|
||||
|
||||
if (foundCompare && foundJump) {
|
||||
|
||||
// If "common" checks fail, bail out on this BB.
|
||||
if (!commonChecksToProhibitNewValueJump(afterRA, MII))
|
||||
break;
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===--- HexagonStoreWidening.cpp------------------------------------------===//
|
||||
//===- HexagonStoreWidening.cpp -------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -27,7 +27,6 @@
|
|||
#include "HexagonRegisterInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "llvm/ADT/SmallPtrSet.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
#include "llvm/Analysis/AliasAnalysis.h"
|
||||
#include "llvm/Analysis/MemoryLocation.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
|
@ -55,8 +54,8 @@ using namespace llvm;
|
|||
|
||||
namespace llvm {
|
||||
|
||||
FunctionPass *createHexagonStoreWidening();
|
||||
void initializeHexagonStoreWideningPass(PassRegistry&);
|
||||
FunctionPass *createHexagonStoreWidening();
|
||||
void initializeHexagonStoreWideningPass(PassRegistry&);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
|
@ -91,8 +90,8 @@ namespace {
|
|||
private:
|
||||
static const int MaxWideSize = 4;
|
||||
|
||||
typedef std::vector<MachineInstr*> InstrGroup;
|
||||
typedef std::vector<InstrGroup> InstrGroupList;
|
||||
using InstrGroup = std::vector<MachineInstr *>;
|
||||
using InstrGroupList = std::vector<InstrGroup>;
|
||||
|
||||
bool instrAliased(InstrGroup &Stores, const MachineMemOperand &MMO);
|
||||
bool instrAliased(InstrGroup &Stores, const MachineInstr *MI);
|
||||
|
@ -109,9 +108,15 @@ namespace {
|
|||
bool storesAreAdjacent(const MachineInstr *S1, const MachineInstr *S2);
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
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...
|
||||
static unsigned getBaseAddressRegister(const MachineInstr *MI) {
|
||||
|
@ -143,12 +148,6 @@ static const MachineMemOperand &getStoreTarget(const MachineInstr *MI) {
|
|||
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
|
||||
// this function will not be subjected to widening.
|
||||
inline bool HexagonStoreWidening::handledStoreType(const MachineInstr *MI) {
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===----- HexagonPacketizer.cpp - vliw packetizer ---------------------===//
|
||||
//===- HexagonPacketizer.cpp - VLIW packetizer ----------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -16,18 +16,38 @@
|
|||
// prune the dependence.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "HexagonVLIWPacketizer.h"
|
||||
#include "Hexagon.h"
|
||||
#include "HexagonInstrInfo.h"
|
||||
#include "HexagonRegisterInfo.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/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/MachineBranchProbabilityInfo.h"
|
||||
#include "llvm/CodeGen/MachineDominators.h"
|
||||
#include "llvm/CodeGen/MachineFrameInfo.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFunctionPass.h"
|
||||
#include "llvm/CodeGen/MachineInstr.h"
|
||||
#include "llvm/CodeGen/MachineLoopInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/CodeGen/MachineOperand.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/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;
|
||||
|
||||
|
@ -51,15 +71,18 @@ static cl::opt<bool> DisableVecDblNVStores("disable-vecdbl-nv-stores",
|
|||
extern cl::opt<bool> ScheduleInlineAsm;
|
||||
|
||||
namespace llvm {
|
||||
FunctionPass *createHexagonPacketizer();
|
||||
void initializeHexagonPacketizerPass(PassRegistry&);
|
||||
}
|
||||
|
||||
FunctionPass *createHexagonPacketizer();
|
||||
void initializeHexagonPacketizerPass(PassRegistry&);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
namespace {
|
||||
|
||||
class HexagonPacketizer : public MachineFunctionPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
HexagonPacketizer() : MachineFunctionPass(ID) {}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
|
@ -72,8 +95,10 @@ namespace {
|
|||
AU.addPreserved<MachineLoopInfo>();
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
|
||||
StringRef getPassName() const override { return "Hexagon Packetizer"; }
|
||||
bool runOnMachineFunction(MachineFunction &Fn) override;
|
||||
|
||||
MachineFunctionProperties getRequiredProperties() const override {
|
||||
return MachineFunctionProperties().set(
|
||||
MachineFunctionProperties::Property::NoVRegs);
|
||||
|
@ -84,8 +109,9 @@ namespace {
|
|||
const HexagonRegisterInfo *HRI;
|
||||
};
|
||||
|
||||
char HexagonPacketizer::ID = 0;
|
||||
}
|
||||
} // end anonymous namespace
|
||||
|
||||
char HexagonPacketizer::ID = 0;
|
||||
|
||||
INITIALIZE_PASS_BEGIN(HexagonPacketizer, "hexagon-packetizer",
|
||||
"Hexagon Packetizer", false, false)
|
||||
|
@ -103,9 +129,9 @@ HexagonPacketizerList::HexagonPacketizerList(MachineFunction &MF,
|
|||
HII = MF.getSubtarget<HexagonSubtarget>().getInstrInfo();
|
||||
HRI = MF.getSubtarget<HexagonSubtarget>().getRegisterInfo();
|
||||
|
||||
addMutation(make_unique<HexagonSubtarget::UsrOverflowMutation>());
|
||||
addMutation(make_unique<HexagonSubtarget::HVXMemLatencyMutation>());
|
||||
addMutation(make_unique<HexagonSubtarget::BankConflictMutation>());
|
||||
addMutation(llvm::make_unique<HexagonSubtarget::UsrOverflowMutation>());
|
||||
addMutation(llvm::make_unique<HexagonSubtarget::HVXMemLatencyMutation>());
|
||||
addMutation(llvm::make_unique<HexagonSubtarget::BankConflictMutation>());
|
||||
}
|
||||
|
||||
// Check if FirstI modifies a register that SecondI reads.
|
||||
|
@ -167,7 +193,6 @@ static MachineBasicBlock::iterator moveInstrOut(MachineInstr &MI,
|
|||
return NextIt;
|
||||
}
|
||||
|
||||
|
||||
bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) {
|
||||
if (DisablePacketizer || skipFunction(*MF.getFunction()))
|
||||
return false;
|
||||
|
@ -187,7 +212,6 @@ bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) {
|
|||
// DFA state table should not be empty.
|
||||
assert(Packetizer.getResourceTracker() && "Empty DFA table!");
|
||||
|
||||
//
|
||||
// Loop over all basic blocks and remove KILL pseudo-instructions
|
||||
// These instructions confuse the dependence analysis. Consider:
|
||||
// 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
|
||||
// dependence between Insn 0 and Insn 2. This can lead to incorrect
|
||||
// packetization
|
||||
//
|
||||
for (auto &MB : MF) {
|
||||
auto End = MB.end();
|
||||
auto MI = MB.begin();
|
||||
|
@ -239,7 +262,6 @@ bool HexagonPacketizer::runOnMachineFunction(MachineFunction &MF) {
|
|||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Reserve resources for a constant extender. Trigger an assertion if the
|
||||
// reservation fails.
|
||||
void HexagonPacketizerList::reserveResourcesForConstExt() {
|
||||
|
@ -262,7 +284,6 @@ bool HexagonPacketizerList::tryAllocateResourcesForConstExt(bool Reserve) {
|
|||
return Avail;
|
||||
}
|
||||
|
||||
|
||||
bool HexagonPacketizerList::isCallDependent(const MachineInstr &MI,
|
||||
SDep::Kind DepType, unsigned DepReg) {
|
||||
// Check for LR dependence.
|
||||
|
@ -308,7 +329,6 @@ static bool isControlFlow(const MachineInstr &MI) {
|
|||
return MI.getDesc().isTerminator() || MI.getDesc().isCall();
|
||||
}
|
||||
|
||||
|
||||
/// Returns true if the instruction modifies a callee-saved register.
|
||||
static bool doesModifyCalleeSavedReg(const MachineInstr &MI,
|
||||
const TargetRegisterInfo *TRI) {
|
||||
|
@ -423,7 +443,7 @@ bool HexagonPacketizerList::canPromoteToDotCur(const MachineInstr &MI,
|
|||
bool HexagonPacketizerList::promoteToDotNew(MachineInstr &MI,
|
||||
SDep::Kind DepType, MachineBasicBlock::iterator &MII,
|
||||
const TargetRegisterClass* RC) {
|
||||
assert (DepType == SDep::Data);
|
||||
assert(DepType == SDep::Data);
|
||||
int NewOpcode;
|
||||
if (RC == &Hexagon::PredRegsRegClass)
|
||||
NewOpcode = HII->getDotNewPredOp(MI, MBPI);
|
||||
|
@ -551,7 +571,6 @@ static const MachineOperand &getAbsSetOperand(const MachineInstr &MI) {
|
|||
return MI.getOperand(1);
|
||||
}
|
||||
|
||||
|
||||
// Can be new value store?
|
||||
// Following restrictions are to be respected in convert a store into
|
||||
// a new value store.
|
||||
|
@ -869,7 +888,6 @@ bool HexagonPacketizerList::restrictingDepExistInPacket(MachineInstr &MI,
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
/// Gets the predicate register of a predicated instruction.
|
||||
static unsigned getPredicatedRegister(MachineInstr &MI,
|
||||
const HexagonInstrInfo *QII) {
|
||||
|
@ -1015,7 +1033,6 @@ bool HexagonPacketizerList::isSoloInstruction(const MachineInstr &MI) {
|
|||
return false;
|
||||
}
|
||||
|
||||
|
||||
// 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",
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
||||
// Full, symmetric check.
|
||||
bool HexagonPacketizerList::cannotCoexist(const MachineInstr &MI,
|
||||
const MachineInstr &MJ) {
|
||||
|
@ -1559,7 +1575,7 @@ HexagonPacketizerList::addToPacket(MachineInstr &MI) {
|
|||
MachineBasicBlock::iterator MII = MI.getIterator();
|
||||
MachineBasicBlock *MBB = MI.getParent();
|
||||
|
||||
if (CurrentPacketMIs.size() == 0)
|
||||
if (CurrentPacketMIs.empty())
|
||||
PacketStalls = false;
|
||||
PacketStalls |= producesStall(MI);
|
||||
|
||||
|
@ -1637,7 +1653,6 @@ bool HexagonPacketizerList::shouldAddToPacket(const MachineInstr &MI) {
|
|||
return !producesStall(MI);
|
||||
}
|
||||
|
||||
|
||||
// V60 forward scheduling.
|
||||
bool HexagonPacketizerList::producesStall(const MachineInstr &I) {
|
||||
// If the packet already stalls, then ignore the stall from a subsequent
|
||||
|
|
|
@ -1,18 +1,33 @@
|
|||
#ifndef HEXAGONVLIWPACKETIZER_H
|
||||
#define HEXAGONVLIWPACKETIZER_H
|
||||
//===- HexagonPacketizer.h - VLIW packetizer --------------------*- C++ -*-===//
|
||||
//
|
||||
// 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/MachineBranchProbabilityInfo.h"
|
||||
#include "llvm/CodeGen/MachineBasicBlock.h"
|
||||
#include "llvm/CodeGen/ScheduleDAG.h"
|
||||
#include "llvm/CodeGen/ScheduleDAGInstrs.h"
|
||||
#include <vector>
|
||||
|
||||
namespace llvm {
|
||||
|
||||
class HexagonInstrInfo;
|
||||
class HexagonRegisterInfo;
|
||||
class MachineBranchProbabilityInfo;
|
||||
class MachineFunction;
|
||||
class MachineInstr;
|
||||
class MachineLoopInfo;
|
||||
class TargetRegisterClass;
|
||||
|
||||
class HexagonPacketizerList : public VLIWPacketizerList {
|
||||
// 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.
|
||||
bool PromotedToDotNew;
|
||||
|
@ -48,7 +63,6 @@ private:
|
|||
const HexagonRegisterInfo *HRI;
|
||||
|
||||
public:
|
||||
// Ctor.
|
||||
HexagonPacketizerList(MachineFunction &MF, MachineLoopInfo &MLI,
|
||||
AliasAnalysis *AA,
|
||||
const MachineBranchProbabilityInfo *MBPI);
|
||||
|
@ -108,9 +122,11 @@ protected:
|
|||
bool isNewifiable(const MachineInstr &MI, const TargetRegisterClass *NewRC);
|
||||
bool isCurifiable(MachineInstr &MI);
|
||||
bool cannotCoexist(const MachineInstr &MI, const MachineInstr &MJ);
|
||||
inline bool isPromotedToDotNew() const {
|
||||
|
||||
bool isPromotedToDotNew() const {
|
||||
return PromotedToDotNew;
|
||||
}
|
||||
|
||||
bool tryAllocateResourcesForConstExt(bool Reserve);
|
||||
bool canReserveResourcesForConstExt();
|
||||
void reserveResourcesForConstExt();
|
||||
|
@ -120,6 +136,7 @@ protected:
|
|||
bool hasV4SpecificDependence(const MachineInstr &I, const MachineInstr &J);
|
||||
bool producesStall(const MachineInstr &MI);
|
||||
};
|
||||
} // namespace llvm
|
||||
#endif // HEXAGONVLIWPACKETIZER_H
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
#endif // LLVM_LIB_TARGET_HEXAGON_HEXAGONVLIWPACKETIZER_H
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// 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
|
||||
// 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
|
||||
// iterations of carried dependence + 1.
|
||||
// 2. All instructions in the DepChain except the last are PHIs.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "hexagon-vlcr"
|
||||
|
||||
#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/Transforms/Scalar.h"
|
||||
#include "llvm/IR/BasicBlock.h"
|
||||
#include "llvm/IR/DerivedTypes.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/IntrinsicInst.h"
|
||||
#include "llvm/ADT/Statistic.h"
|
||||
#include <set>
|
||||
#include "llvm/IR/Intrinsics.h"
|
||||
#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 <memory>
|
||||
#include <set>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "hexagon-vlcr"
|
||||
|
||||
STATISTIC(HexagonNumVectorLoopCarriedReuse,
|
||||
"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::desc("Maximum distance of loop carried dependences that are handled"),
|
||||
cl::init(2), cl::ZeroOrMore);
|
||||
|
||||
namespace llvm {
|
||||
void initializeHexagonVectorLoopCarriedReusePass(PassRegistry&);
|
||||
Pass *createHexagonVectorLoopCarriedReusePass();
|
||||
}
|
||||
|
||||
void initializeHexagonVectorLoopCarriedReusePass(PassRegistry&);
|
||||
Pass *createHexagonVectorLoopCarriedReusePass();
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
namespace {
|
||||
|
||||
// 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 {
|
||||
ChainOfDependences Chain;
|
||||
|
||||
public:
|
||||
bool isIdentical(DepChain &Other) {
|
||||
bool isIdentical(DepChain &Other) const {
|
||||
if (Other.size() != size())
|
||||
return false;
|
||||
ChainOfDependences &OtherChain = Other.getChain();
|
||||
|
@ -156,30 +183,39 @@ namespace {
|
|||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
ChainOfDependences &getChain() {
|
||||
return Chain;
|
||||
}
|
||||
int size() {
|
||||
|
||||
int size() const {
|
||||
return Chain.size();
|
||||
}
|
||||
|
||||
void clear() {
|
||||
Chain.clear();
|
||||
}
|
||||
|
||||
void push_back(Instruction *I) {
|
||||
Chain.push_back(I);
|
||||
}
|
||||
int iterations() {
|
||||
|
||||
int iterations() const {
|
||||
return size() - 1;
|
||||
}
|
||||
Instruction *front() {
|
||||
|
||||
Instruction *front() const {
|
||||
return Chain.front();
|
||||
}
|
||||
Instruction *back() {
|
||||
|
||||
Instruction *back() const {
|
||||
return Chain.back();
|
||||
}
|
||||
|
||||
Instruction *&operator[](const int index) {
|
||||
return Chain[index];
|
||||
}
|
||||
|
||||
friend raw_ostream &operator<< (raw_ostream &OS, const DepChain &D);
|
||||
};
|
||||
|
||||
|
@ -194,19 +230,21 @@ namespace {
|
|||
OS << *CD[ChainSize-1] << "\n";
|
||||
return OS;
|
||||
}
|
||||
}
|
||||
namespace {
|
||||
|
||||
struct ReuseValue {
|
||||
Instruction *Inst2Replace;
|
||||
Instruction *Inst2Replace = nullptr;
|
||||
|
||||
// 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
|
||||
// previous iteration.
|
||||
Instruction * BackedgeInst;
|
||||
ReuseValue() : Inst2Replace(nullptr), BackedgeInst(nullptr) {};
|
||||
Instruction *BackedgeInst = nullptr;
|
||||
|
||||
ReuseValue() = default;
|
||||
|
||||
void reset() { Inst2Replace = nullptr; BackedgeInst = nullptr; }
|
||||
bool isDefined() { return Inst2Replace != nullptr; }
|
||||
};
|
||||
typedef struct ReuseValue ReuseValue;
|
||||
|
||||
LLVM_ATTRIBUTE_UNUSED
|
||||
raw_ostream &operator<<(raw_ostream &OS, const ReuseValue &RU) {
|
||||
OS << "** ReuseValue ***\n";
|
||||
|
@ -214,16 +252,16 @@ namespace {
|
|||
OS << "Backedge Instruction: " << *(RU.BackedgeInst) << "\n";
|
||||
return OS;
|
||||
}
|
||||
}
|
||||
|
||||
namespace {
|
||||
class HexagonVectorLoopCarriedReuse : public LoopPass {
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
explicit HexagonVectorLoopCarriedReuse() : LoopPass(ID) {
|
||||
PassRegistry *PR = PassRegistry::getPassRegistry();
|
||||
initializeHexagonVectorLoopCarriedReusePass(*PR);
|
||||
}
|
||||
|
||||
StringRef getPassName() const override {
|
||||
return "Hexagon-specific loop carried reuse for HVX vectors";
|
||||
}
|
||||
|
@ -254,9 +292,9 @@ namespace {
|
|||
DepChain *getDepChainBtwn(Instruction *I1, Instruction *I2);
|
||||
bool isEquivalentOperation(Instruction *I1, Instruction *I2);
|
||||
bool canReplace(Instruction *I);
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char HexagonVectorLoopCarriedReuse::ID = 0;
|
||||
|
||||
|
@ -276,7 +314,7 @@ bool HexagonVectorLoopCarriedReuse::runOnLoop(Loop *L, LPPassManager &LPM) {
|
|||
return false;
|
||||
|
||||
// Work only on innermost loops.
|
||||
if (L->getSubLoops().size() != 0)
|
||||
if (!L->getSubLoops().empty())
|
||||
return false;
|
||||
|
||||
// Work only on single basic blocks loops.
|
||||
|
@ -396,8 +434,8 @@ void HexagonVectorLoopCarriedReuse::findValueToReuse() {
|
|||
}
|
||||
}
|
||||
ReuseCandidate.reset();
|
||||
return;
|
||||
}
|
||||
|
||||
Value *HexagonVectorLoopCarriedReuse::findValueInBlock(Value *Op,
|
||||
BasicBlock *BB) {
|
||||
PHINode *PN = dyn_cast<PHINode>(Op);
|
||||
|
@ -405,6 +443,7 @@ Value *HexagonVectorLoopCarriedReuse::findValueInBlock(Value *Op,
|
|||
Value *ValueInBlock = PN->getIncomingValueForBlock(BB);
|
||||
return ValueInBlock;
|
||||
}
|
||||
|
||||
void HexagonVectorLoopCarriedReuse::reuseValue() {
|
||||
DEBUG(dbgs() << ReuseCandidate);
|
||||
Instruction *Inst2Replace = ReuseCandidate.Inst2Replace;
|
||||
|
@ -476,7 +515,7 @@ void HexagonVectorLoopCarriedReuse::reuseValue() {
|
|||
}
|
||||
|
||||
bool HexagonVectorLoopCarriedReuse::doVLCR() {
|
||||
assert((CurLoop->getSubLoops().size() == 0) &&
|
||||
assert(CurLoop->getSubLoops().empty() &&
|
||||
"Can do VLCR on the innermost loop only");
|
||||
assert((CurLoop->getNumBlocks() == 1) &&
|
||||
"Can do VLCR only on single block loops");
|
||||
|
@ -502,6 +541,7 @@ bool HexagonVectorLoopCarriedReuse::doVLCR() {
|
|||
} while (Continue);
|
||||
return Changed;
|
||||
}
|
||||
|
||||
void HexagonVectorLoopCarriedReuse::findDepChainFromPHI(Instruction *I,
|
||||
DepChain &D) {
|
||||
PHINode *PN = dyn_cast<PHINode>(I);
|
||||
|
@ -536,7 +576,6 @@ void HexagonVectorLoopCarriedReuse::findDepChainFromPHI(Instruction *I,
|
|||
D.push_back(PN);
|
||||
findDepChainFromPHI(BEInst, D);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
bool HexagonVectorLoopCarriedReuse::isDepChainBtwn(Instruction *I1,
|
||||
|
@ -548,6 +587,7 @@ bool HexagonVectorLoopCarriedReuse::isDepChainBtwn(Instruction *I1,
|
|||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
DepChain *HexagonVectorLoopCarriedReuse::getDepChainBtwn(Instruction *I1,
|
||||
Instruction *I2) {
|
||||
for (auto *D : Dependences) {
|
||||
|
@ -556,6 +596,7 @@ DepChain *HexagonVectorLoopCarriedReuse::getDepChainBtwn(Instruction *I1,
|
|||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void HexagonVectorLoopCarriedReuse::findLoopCarriedDeps() {
|
||||
BasicBlock *BB = CurLoop->getHeader();
|
||||
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";
|
||||
});
|
||||
}
|
||||
|
||||
Pass *llvm::createHexagonVectorLoopCarriedReusePass() {
|
||||
return new HexagonVectorLoopCarriedReuse();
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
//===-- HexagonVectorPrint.cpp - Generate vector printing instructions -===//
|
||||
//===- HexagonVectorPrint.cpp - Generate vector printing instructions -----===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
|
@ -13,8 +13,6 @@
|
|||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#define DEBUG_TYPE "hexagon-vector-print"
|
||||
|
||||
#include "HexagonInstrInfo.h"
|
||||
#include "HexagonSubtarget.h"
|
||||
#include "llvm/ADT/StringRef.h"
|
||||
|
@ -31,34 +29,36 @@
|
|||
#include "llvm/Support/Debug.h"
|
||||
#include "llvm/Support/ErrorHandling.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include "llvm/Target/TargetOpcodes.h"
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
#define DEBUG_TYPE "hexagon-vector-print"
|
||||
|
||||
static cl::opt<bool> TraceHexVectorStoresOnly("trace-hex-vector-stores-only",
|
||||
cl::Hidden, cl::ZeroOrMore, cl::init(false),
|
||||
cl::desc("Enables tracing of vector stores"));
|
||||
|
||||
namespace llvm {
|
||||
|
||||
FunctionPass *createHexagonVectorPrint();
|
||||
void initializeHexagonVectorPrintPass(PassRegistry&);
|
||||
FunctionPass *createHexagonVectorPrint();
|
||||
void initializeHexagonVectorPrintPass(PassRegistry&);
|
||||
|
||||
} // end namespace llvm
|
||||
|
||||
namespace {
|
||||
|
||||
class HexagonVectorPrint : public MachineFunctionPass {
|
||||
const HexagonSubtarget *QST;
|
||||
const HexagonInstrInfo *QII;
|
||||
const HexagonRegisterInfo *QRI;
|
||||
const HexagonSubtarget *QST = nullptr;
|
||||
const HexagonInstrInfo *QII = nullptr;
|
||||
const HexagonRegisterInfo *QRI = nullptr;
|
||||
|
||||
public:
|
||||
static char ID;
|
||||
|
||||
HexagonVectorPrint()
|
||||
: MachineFunctionPass(ID), QST(nullptr), QII(nullptr), QRI(nullptr) {
|
||||
HexagonVectorPrint() : MachineFunctionPass(ID) {
|
||||
initializeHexagonVectorPrintPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
|
@ -67,10 +67,10 @@ public:
|
|||
bool runOnMachineFunction(MachineFunction &Fn) override;
|
||||
};
|
||||
|
||||
char HexagonVectorPrint::ID = 0;
|
||||
|
||||
} // end anonymous namespace
|
||||
|
||||
char HexagonVectorPrint::ID = 0;
|
||||
|
||||
static bool isVecReg(unsigned Reg) {
|
||||
return (Reg >= Hexagon::V0 && Reg <= Hexagon::V31)
|
||||
|| (Reg >= Hexagon::W0 && Reg <= Hexagon::W15)
|
||||
|
@ -97,7 +97,6 @@ static void addAsmInstr(MachineBasicBlock *MBB, unsigned Reg,
|
|||
MachineBasicBlock::instr_iterator I,
|
||||
const DebugLoc &DL, const HexagonInstrInfo *QII,
|
||||
MachineFunction &Fn) {
|
||||
|
||||
std::string VDescStr = ".long 0x1dffe0" + getStringReg(Reg);
|
||||
const char *cstr = Fn.createExternalSymbolName(VDescStr);
|
||||
unsigned ExtraInfo = InlineAsm::Extra_HasSideEffects;
|
||||
|
|
Loading…
Reference in New Issue