[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 "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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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)
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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) {
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
Loading…
Reference in New Issue