mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-22 02:33:06 +01:00
Revert "LiveIntervalAnalysis: Remove LiveVariables requirement" and LiveIntervalTest
The commit breaks stage2 compilation on PowerPC. Reverting for now while this is analyzed. I also have to revert the LiveIntervalTest for now as that depends on this commit. Revert "LiveIntervalAnalysis: Remove LiveVariables requirement" This reverts commit r260806. Revert "Remove an unnecessary std::move to fix -Wpessimizing-move warning." This reverts commit r260931. Revert "Fix typo in LiveIntervalTest" This reverts commit r260907. Revert "Add unittest for LiveIntervalAnalysis::handleMove()" This reverts commit r260905. llvm-svn: 261189
This commit is contained in:
parent
be811f1963
commit
3109aeee9b
@ -9,7 +9,8 @@
|
||||
//
|
||||
// This file implements the LiveInterval analysis pass which is used
|
||||
// by the Linear Scan Register allocator. This pass linearizes the
|
||||
// basic blocks of the function in DFS order and computes live intervals for
|
||||
// basic blocks of the function in DFS order and uses the
|
||||
// LiveVariables pass to conservatively compute live intervals for
|
||||
// each virtual and physical register.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -47,6 +48,7 @@ char &llvm::LiveIntervalsID = LiveIntervals::ID;
|
||||
INITIALIZE_PASS_BEGIN(LiveIntervals, "liveintervals",
|
||||
"Live Interval Analysis", false, false)
|
||||
INITIALIZE_PASS_DEPENDENCY(AAResultsWrapperPass)
|
||||
INITIALIZE_PASS_DEPENDENCY(LiveVariables)
|
||||
INITIALIZE_PASS_DEPENDENCY(MachineDominatorTree)
|
||||
INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
|
||||
INITIALIZE_PASS_END(LiveIntervals, "liveintervals",
|
||||
@ -75,6 +77,10 @@ void LiveIntervals::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
AU.addPreserved<AAResultsWrapperPass>();
|
||||
// LiveVariables isn't really required by this analysis, it is only required
|
||||
// here to make sure it is live during TwoAddressInstructionPass and
|
||||
// PHIElimination. This is temporary.
|
||||
AU.addRequired<LiveVariables>();
|
||||
AU.addPreserved<LiveVariables>();
|
||||
AU.addPreservedID(MachineLoopInfoID);
|
||||
AU.addRequiredTransitiveID(MachineDominatorsID);
|
||||
|
@ -121,7 +121,6 @@ INITIALIZE_PASS_END(PHIElimination, "phi-node-elimination",
|
||||
"Eliminate PHI nodes for register allocation", false, false)
|
||||
|
||||
void PHIElimination::getAnalysisUsage(AnalysisUsage &AU) const {
|
||||
AU.addUsedIfAvailable<LiveVariables>();
|
||||
AU.addPreserved<LiveVariables>();
|
||||
AU.addPreserved<SlotIndexes>();
|
||||
AU.addPreserved<LiveIntervals>();
|
||||
|
@ -157,7 +157,6 @@ public:
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.setPreservesCFG();
|
||||
AU.addRequired<AAResultsWrapperPass>();
|
||||
AU.addUsedIfAvailable<LiveVariables>();
|
||||
AU.addPreserved<LiveVariables>();
|
||||
AU.addPreserved<SlotIndexes>();
|
||||
AU.addPreserved<LiveIntervals>();
|
||||
|
@ -22,7 +22,6 @@ add_subdirectory(IR)
|
||||
add_subdirectory(LineEditor)
|
||||
add_subdirectory(Linker)
|
||||
add_subdirectory(MC)
|
||||
add_subdirectory(MI)
|
||||
add_subdirectory(Option)
|
||||
add_subdirectory(ProfileData)
|
||||
add_subdirectory(Support)
|
||||
|
@ -1,14 +0,0 @@
|
||||
set(LLVM_LINK_COMPONENTS
|
||||
${LLVM_TARGETS_TO_BUILD}
|
||||
AsmPrinter
|
||||
CodeGen
|
||||
Core
|
||||
MC
|
||||
MIRParser
|
||||
Support
|
||||
Target
|
||||
)
|
||||
|
||||
add_llvm_unittest(MITests
|
||||
LiveIntervalTest.cpp
|
||||
)
|
@ -1,306 +0,0 @@
|
||||
#include "gtest/gtest.h"
|
||||
#include "llvm/ADT/STLExtras.h"
|
||||
#include "llvm/CodeGen/LiveIntervalAnalysis.h"
|
||||
#include "llvm/CodeGen/MIRParser/MIRParser.h"
|
||||
#include "llvm/CodeGen/MachineFunction.h"
|
||||
#include "llvm/CodeGen/MachineFunctionAnalysis.h"
|
||||
#include "llvm/CodeGen/MachineModuleInfo.h"
|
||||
#include "llvm/CodeGen/MachineRegisterInfo.h"
|
||||
#include "llvm/CodeGen/Passes.h"
|
||||
#include "llvm/Support/MemoryBuffer.h"
|
||||
#include "llvm/Support/SourceMgr.h"
|
||||
#include "llvm/Support/TargetRegistry.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
#include "llvm/Target/TargetOptions.h"
|
||||
#include "llvm/Target/TargetRegisterInfo.h"
|
||||
#include "llvm/IR/LegacyPassManager.h"
|
||||
|
||||
using namespace llvm;
|
||||
|
||||
namespace llvm {
|
||||
void initializeTestPassPass(PassRegistry &);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
void initLLVM() {
|
||||
InitializeAllTargets();
|
||||
InitializeAllTargetMCs();
|
||||
InitializeAllAsmPrinters();
|
||||
InitializeAllAsmParsers();
|
||||
|
||||
PassRegistry *Registry = PassRegistry::getPassRegistry();
|
||||
initializeCore(*Registry);
|
||||
initializeCodeGen(*Registry);
|
||||
}
|
||||
|
||||
/// Create a TargetMachine. As we lack a dedicated always available target for
|
||||
/// unittests, we go for "x86_64" which should be available in most builds.
|
||||
std::unique_ptr<TargetMachine> createTargetMachine() {
|
||||
Triple TargetTriple("x86_64--");
|
||||
std::string Error;
|
||||
const Target *T = TargetRegistry::lookupTarget("", TargetTriple, Error);
|
||||
if (!T)
|
||||
return nullptr;
|
||||
|
||||
TargetOptions Options;
|
||||
return std::unique_ptr<TargetMachine>(
|
||||
T->createTargetMachine("x86_64", "", "", Options, Reloc::Default,
|
||||
CodeModel::Default, CodeGenOpt::Aggressive));
|
||||
}
|
||||
|
||||
std::unique_ptr<Module> parseMIR(legacy::PassManagerBase &PM,
|
||||
std::unique_ptr<MIRParser> &MIR, const TargetMachine &TM,
|
||||
StringRef MIRCode, const char *FuncName) {
|
||||
LLVMContext &Context = getGlobalContext();
|
||||
|
||||
SMDiagnostic Diagnostic;
|
||||
std::unique_ptr<MemoryBuffer> MBuffer = MemoryBuffer::getMemBuffer(MIRCode);
|
||||
MIR = createMIRParser(std::move(MBuffer), Context);
|
||||
if (!MIR)
|
||||
return nullptr;
|
||||
|
||||
std::unique_ptr<Module> M = MIR->parseLLVMModule();
|
||||
if (!M)
|
||||
return nullptr;
|
||||
|
||||
M->setDataLayout(TM.createDataLayout());
|
||||
|
||||
Function *F = M->getFunction(FuncName);
|
||||
if (!F)
|
||||
return nullptr;
|
||||
|
||||
MachineModuleInfo *MMI = new MachineModuleInfo(
|
||||
*TM.getMCAsmInfo(), *TM.getMCRegisterInfo(), nullptr);
|
||||
PM.add(MMI);
|
||||
|
||||
MachineFunctionAnalysis *MFA = new MachineFunctionAnalysis(TM, MIR.get());
|
||||
PM.add(MFA);
|
||||
|
||||
return M;
|
||||
}
|
||||
|
||||
typedef std::function<void(MachineFunction&,LiveIntervals&)> LiveIntervalTest;
|
||||
|
||||
struct TestPass : public MachineFunctionPass {
|
||||
static char ID;
|
||||
TestPass() : MachineFunctionPass(ID) {
|
||||
// We should never call this but always use PM.add(new TestPass(...))
|
||||
abort();
|
||||
}
|
||||
TestPass(LiveIntervalTest T) : MachineFunctionPass(ID), T(T) {
|
||||
initializeTestPassPass(*PassRegistry::getPassRegistry());
|
||||
}
|
||||
|
||||
bool runOnMachineFunction(MachineFunction &MF) override {
|
||||
LiveIntervals &LIS = getAnalysis<LiveIntervals>();
|
||||
T(MF, LIS);
|
||||
EXPECT_TRUE(MF.verify(this));
|
||||
return true;
|
||||
}
|
||||
|
||||
void getAnalysisUsage(AnalysisUsage &AU) const override {
|
||||
AU.setPreservesAll();
|
||||
AU.addRequired<LiveIntervals>();
|
||||
AU.addPreserved<LiveIntervals>();
|
||||
MachineFunctionPass::getAnalysisUsage(AU);
|
||||
}
|
||||
private:
|
||||
LiveIntervalTest T;
|
||||
};
|
||||
|
||||
/**
|
||||
* Move instruction number \p From in front of instruction number \p To and
|
||||
* update affected liveness intervals with LiveIntervalAnalysis::handleMove().
|
||||
*/
|
||||
void Move(MachineFunction &MF, LiveIntervals &LIS, unsigned From, unsigned To) {
|
||||
MachineBasicBlock &MBB = MF.front();
|
||||
|
||||
unsigned I = 0;
|
||||
MachineInstr *FromInstr = nullptr;
|
||||
MachineInstr *ToInstr = nullptr;
|
||||
for (MachineInstr &MI : MBB) {
|
||||
if (I == From)
|
||||
FromInstr = &MI;
|
||||
if (I == To)
|
||||
ToInstr = &MI;
|
||||
++I;
|
||||
}
|
||||
assert(FromInstr != nullptr && ToInstr != nullptr);
|
||||
|
||||
MBB.splice(ToInstr->getIterator(), &MBB, FromInstr->getIterator());
|
||||
LIS.handleMove(FromInstr, true);
|
||||
}
|
||||
|
||||
void DoLiveIntervalTest(StringRef MIRFunc, LiveIntervalTest T) {
|
||||
std::unique_ptr<TargetMachine> TM = createTargetMachine();
|
||||
// This test is designed for the X86 backend; stop if it is not available.
|
||||
if (!TM)
|
||||
return;
|
||||
|
||||
legacy::PassManager PM;
|
||||
|
||||
SmallString<160> S;
|
||||
StringRef MIRString = (Twine(
|
||||
"---\n"
|
||||
"...\n"
|
||||
"name: func\n"
|
||||
"registers:\n"
|
||||
" - { id: 0, class: gr64 }\n"
|
||||
"body: |\n"
|
||||
" bb.0:\n"
|
||||
) + Twine(MIRFunc) + Twine("...\n")).toNullTerminatedStringRef(S);
|
||||
std::unique_ptr<MIRParser> MIR;
|
||||
std::unique_ptr<Module> M = parseMIR(PM, MIR, *TM, MIRString, "func");
|
||||
|
||||
PM.add(new TestPass(T));
|
||||
|
||||
PM.run(*M);
|
||||
}
|
||||
|
||||
} // End of anonymous namespace.
|
||||
|
||||
char TestPass::ID = 0;
|
||||
INITIALIZE_PASS(TestPass, "testpass", "testpass", false, false)
|
||||
|
||||
TEST(LiveIntervalTest, MoveUpDef) {
|
||||
// Value defined.
|
||||
DoLiveIntervalTest(
|
||||
" NOOP\n"
|
||||
" NOOP\n"
|
||||
" early-clobber %0 = IMPLICIT_DEF\n"
|
||||
" RETQ %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 2, 1);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LiveIntervalTest, MoveUpRedef) {
|
||||
DoLiveIntervalTest(
|
||||
" %0 = IMPLICIT_DEF\n"
|
||||
" NOOP\n"
|
||||
" %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
|
||||
" RETQ %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 2, 1);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LiveIntervalTest, MoveUpEarlyDef) {
|
||||
DoLiveIntervalTest(
|
||||
" NOOP\n"
|
||||
" NOOP\n"
|
||||
" early-clobber %0 = IMPLICIT_DEF\n"
|
||||
" RETQ %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 2, 1);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LiveIntervalTest, MoveUpEarlyRedef) {
|
||||
DoLiveIntervalTest(
|
||||
" %0 = IMPLICIT_DEF\n"
|
||||
" NOOP\n"
|
||||
" early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
|
||||
" RETQ %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 2, 1);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LiveIntervalTest, MoveUpKill) {
|
||||
DoLiveIntervalTest(
|
||||
" %0 = IMPLICIT_DEF\n"
|
||||
" NOOP\n"
|
||||
" NOOP implicit %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 2, 1);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LiveIntervalTest, MoveUpKillFollowing) {
|
||||
DoLiveIntervalTest(
|
||||
" %0 = IMPLICIT_DEF\n"
|
||||
" NOOP\n"
|
||||
" NOOP implicit %0\n"
|
||||
" RETQ %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 2, 1);
|
||||
});
|
||||
}
|
||||
|
||||
// TODO: Construct a situation where we have intervals following a hole
|
||||
// while still having connected components.
|
||||
|
||||
TEST(LiveIntervalTest, MoveDownDef) {
|
||||
// Value defined.
|
||||
DoLiveIntervalTest(
|
||||
" NOOP\n"
|
||||
" early-clobber %0 = IMPLICIT_DEF\n"
|
||||
" NOOP\n"
|
||||
" RETQ %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 1, 2);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LiveIntervalTest, MoveDownRedef) {
|
||||
DoLiveIntervalTest(
|
||||
" %0 = IMPLICIT_DEF\n"
|
||||
" %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
|
||||
" NOOP\n"
|
||||
" RETQ %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 1, 2);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LiveIntervalTest, MoveDownEarlyDef) {
|
||||
DoLiveIntervalTest(
|
||||
" NOOP\n"
|
||||
" early-clobber %0 = IMPLICIT_DEF\n"
|
||||
" NOOP\n"
|
||||
" RETQ %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 1, 2);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LiveIntervalTest, MoveDownEarlyRedef) {
|
||||
DoLiveIntervalTest(
|
||||
" %0 = IMPLICIT_DEF\n"
|
||||
" early-clobber %0 = IMPLICIT_DEF implicit %0(tied-def 0)\n"
|
||||
" NOOP\n"
|
||||
" RETQ %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 1, 2);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LiveIntervalTest, MoveDownKill) {
|
||||
DoLiveIntervalTest(
|
||||
" %0 = IMPLICIT_DEF\n"
|
||||
" NOOP implicit %0\n"
|
||||
" NOOP\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 1, 2);
|
||||
});
|
||||
}
|
||||
|
||||
TEST(LiveIntervalTest, MoveDownKillFollowing) {
|
||||
DoLiveIntervalTest(
|
||||
" %0 = IMPLICIT_DEF\n"
|
||||
" NOOP\n"
|
||||
" NOOP implicit %0\n"
|
||||
" RETQ %0\n",
|
||||
[](MachineFunction &MF, LiveIntervals &LIS) {
|
||||
Move(MF, LIS, 1, 2);
|
||||
});
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
initLLVM();
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
Loading…
Reference in New Issue
Block a user