aboutsummaryrefslogtreecommitdiff
path: root/backend/unittests/CodeGen/LivePhysRegsTest.cpp
blob: ee579be0d767e8582ce46f40ac0bd1fb26c9b3b4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
// SPDX-License-Identifier: GPL-3.0-or-later

#include "rcc/CodeGen/LivePhysRegs.h"

#include "LiveTestSupport.h"
#include "rcc/CodeGen/LiveVariables.h"

namespace {

using namespace rcc::test::liveness;

void testPostRALivenessRepair(TestContext &Context, const rcc::TargetDescription &Target) {
  auto Fixture = createFunction("post-ra-repair", 12, 1);
  if (!Fixture) {
    Context.expect(false, "post-RA repair fixture creation must succeed");
    return;
  }
  const rcc::Register G0 = rcc::Register::fromPhysical(physical(rcc::test::TestRegister::G0));
  auto Def = buildDef(*Fixture->Function, Target, *Fixture->Blocks[0], G0);
  auto FirstUse = buildUse(*Fixture->Function, Target, *Fixture->Blocks[0], G0);
  auto LastUse = buildUse(*Fixture->Function, Target, *Fixture->Blocks[0], G0);
  if (!Def || !FirstUse || !LastUse) {
    Context.expect(false, "post-RA repair instructions must be built");
    return;
  }

  rcc::MachineAnalysisManager Analyses;
  auto Registered = rcc::registerStage11MachineAnalyses(Analyses);
  auto Liveness = Registered
                      ? Analyses.getResult<rcc::LiveVariablesAnalysis>(*Fixture->Function, Target)
                      : rcc::Expected<rcc::LiveVariablesAnalysis::Result *>{
                            std::unexpected(Registered.error())};
  if (!Liveness) {
    Context.expect(false, "post-RA repair liveness must materialize");
    return;
  }
  const std::array Blocks{Fixture->Blocks[0]};
  auto Repaired = rcc::repairPostRAMachineBlockLiveness(Blocks, Target, **Liveness);
  Context.expect(Repaired && *Repaired, "post-RA repair must update stale kill/dead flags");
  Context.expect(!hasFlag(**Def, 0, rcc::RegisterOperandFlag::Dead) &&
                     !hasFlag(**FirstUse, 0, rcc::RegisterOperandFlag::Kill) &&
                     hasFlag(**LastUse, 0, rcc::RegisterOperandFlag::Kill),
                 "post-RA repair must derive precise physical kill/dead flags");
}

} // namespace

int main() {
  TestContext Context;
  auto Target = createTarget();
  Context.expect(Target.has_value(), "liveness TestTarget must be created");
  if (!Target)
    return Context.result();
  testPostRALivenessRepair(Context, *Target);
  return Context.result();
}