Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[LLVM] Add HasFakeUses to MachineFunction #110097

Merged
merged 3 commits into from
Oct 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions llvm/include/llvm/CodeGen/MIRYamlMapping.h
Original file line number Diff line number Diff line change
Expand Up @@ -734,6 +734,7 @@ struct MachineFunction {
std::optional<bool> NoPHIs;
std::optional<bool> IsSSA;
std::optional<bool> NoVRegs;
std::optional<bool> HasFakeUses;

bool CallsEHReturn = false;
bool CallsUnwindInit = false;
Expand Down Expand Up @@ -780,6 +781,7 @@ template <> struct MappingTraits<MachineFunction> {
YamlIO.mapOptional("noPhis", MF.NoPHIs, std::optional<bool>());
YamlIO.mapOptional("isSSA", MF.IsSSA, std::optional<bool>());
YamlIO.mapOptional("noVRegs", MF.NoVRegs, std::optional<bool>());
YamlIO.mapOptional("hasFakeUses", MF.HasFakeUses, std::optional<bool>());

YamlIO.mapOptional("callsEHReturn", MF.CallsEHReturn, false);
YamlIO.mapOptional("callsUnwindInit", MF.CallsUnwindInit, false);
Expand Down
5 changes: 5 additions & 0 deletions llvm/include/llvm/CodeGen/MachineFunction.h
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,7 @@ class MachineFunctionProperties {
TiedOpsRewritten,
FailsVerification,
TracksDebugUserValues,
HasFakeUses,
LastProperty = TracksDebugUserValues,
};

Expand Down Expand Up @@ -376,6 +377,7 @@ class LLVM_ABI MachineFunction {
bool HasEHCatchret = false;
bool HasEHScopes = false;
bool HasEHFunclets = false;
bool HasFakeUses = false;
bool IsOutlined = false;

/// BBID to assign to the next basic block of this function.
Expand Down Expand Up @@ -1200,6 +1202,9 @@ class LLVM_ABI MachineFunction {
bool hasEHFunclets() const { return HasEHFunclets; }
void setHasEHFunclets(bool V) { HasEHFunclets = V; }

bool hasFakeUses() const { return HasFakeUses; }
void setHasFakeUses(bool V) { HasFakeUses = V; }

bool isOutlined() const { return IsOutlined; }
void setIsOutlined(bool V) { IsOutlined = V; }

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2199,6 +2199,7 @@ bool IRTranslator::translateKnownIntrinsic(const CallInst &CI, Intrinsic::ID ID,
for (auto VReg : getOrCreateVRegs(*Arg))
VRegs.push_back(VReg);
MIRBuilder.buildInstr(TargetOpcode::FAKE_USE, {}, VRegs);
MF->setHasFakeUses(true);
return true;
}
case Intrinsic::dbg_declare: {
Expand Down
13 changes: 13 additions & 0 deletions llvm/lib/CodeGen/MIRParser/MIRParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -380,13 +380,16 @@ bool MIRParserImpl::computeFunctionProperties(

bool HasPHI = false;
bool HasInlineAsm = false;
bool HasFakeUses = false;
bool AllTiedOpsRewritten = true, HasTiedOps = false;
for (const MachineBasicBlock &MBB : MF) {
for (const MachineInstr &MI : MBB) {
if (MI.isPHI())
HasPHI = true;
if (MI.isInlineAsm())
HasInlineAsm = true;
if (MI.isFakeUse())
HasFakeUses = true;
for (unsigned I = 0; I < MI.getNumOperands(); ++I) {
const MachineOperand &MO = MI.getOperand(I);
if (!MO.isReg() || !MO.getReg())
Expand Down Expand Up @@ -441,6 +444,16 @@ bool MIRParserImpl::computeFunctionProperties(
" has explicit property NoVRegs, but contains virtual registers");
}

// For hasFakeUses we follow similar logic to the ComputedPropertyHelper,
// except for caring about the inverse case only, i.e. when the property is
// explicitly set to false and Fake Uses are present; having HasFakeUses=true
// on a function without fake uses is harmless.
if (YamlMF.HasFakeUses && !*YamlMF.HasFakeUses && HasFakeUses)
return error(
MF.getName() +
" has explicit property hasFakeUses=false, but contains fake uses");
MF.setHasFakeUses(YamlMF.HasFakeUses.value_or(HasFakeUses));

return false;
}

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/CodeGen/MIRPrinter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,7 @@ void MIRPrinter::print(const MachineFunction &MF) {
YamlMF.HasEHCatchret = MF.hasEHCatchret();
YamlMF.HasEHScopes = MF.hasEHScopes();
YamlMF.HasEHFunclets = MF.hasEHFunclets();
YamlMF.HasFakeUses = MF.hasFakeUses();
YamlMF.IsOutlined = MF.isOutlined();
YamlMF.UseDebugInstrRef = MF.useDebugInstrRef();

Expand Down
6 changes: 2 additions & 4 deletions llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -74,10 +74,8 @@ INITIALIZE_PASS_END(RemoveLoadsIntoFakeUses, DEBUG_TYPE,
"Remove Loads Into Fake Uses", false, false)

bool RemoveLoadsIntoFakeUses::runOnMachineFunction(MachineFunction &MF) {
// Only `optdebug` functions should contain FAKE_USEs, so don't try to run
// this for other functions.
if (!MF.getFunction().hasFnAttribute(Attribute::OptimizeForDebugging) ||
skipFunction(MF.getFunction()))
// Only run this for functions that have fake uses.
if (!MF.hasFakeUses() || skipFunction(MF.getFunction()))
return false;

bool AnyChanges = false;
Expand Down
19 changes: 15 additions & 4 deletions llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
Expand Down Expand Up @@ -200,12 +201,22 @@ void FunctionLoweringInfo::set(const Function &fn, MachineFunction &mf,
}
}
}
// Look for calls to the @llvm.va_start intrinsic. We can omit some
// prologue boilerplate for variadic functions that don't examine their
// arguments.
if (const auto *II = dyn_cast<IntrinsicInst>(&I)) {
if (II->getIntrinsicID() == Intrinsic::vastart)
switch (II->getIntrinsicID()) {
case Intrinsic::vastart:
// Look for calls to the @llvm.va_start intrinsic. We can omit
// some prologue boilerplate for variadic functions that don't
// examine their arguments.
MF->getFrameInfo().setHasVAStart(true);
break;
case Intrinsic::fake_use:
// Look for llvm.fake.uses, so that we can remove loads into fake
// uses later if necessary.
MF->setHasFakeUses(true);
break;
default:
break;
}
}

// If we have a musttail call in a variadic function, we need to ensure
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# RUN: not llc -run-pass none -o /dev/null %s 2>&1 | FileCheck %s

# Test that computed properties are not conflicting with explicitly set
# properties

---
# CHECK: error: {{.*}}: TestHasFakeUsesOverrideConflict has explicit property hasFakeUses=false, but contains fake uses
name: TestHasFakeUsesOverrideConflict
hasFakeUses: false
body: |
bb.0:
%0:_(s32) = G_IMPLICIT_DEF
FAKE_USE %0
...
Original file line number Diff line number Diff line change
Expand Up @@ -62,3 +62,23 @@ noVRegs: false
name: TestNoVRegsOverrideTrue
noVRegs: true
...
---
# CHECK-LABEL: name: TestHasFakeUses
# CHECK: hasFakeUses: false
# CHECK: ...
name: TestHasFakeUses
...
---
# CHECK-LABEL: name: TestHasFakeUsesOverride
# CHECK: hasFakeUses: false
# CHECK: ...
name: TestHasFakeUsesOverride
hasFakeUses: false
...
---
# CHECK-LABEL: name: TestHasFakeUsesOverrideTrue
# CHECK: hasFakeUses: true
# CHECK: ...
name: TestHasFakeUsesOverrideTrue
hasFakeUses: true
...
2 changes: 2 additions & 0 deletions llvm/test/tools/llvm-reduce/mir/preserve-func-info.mir
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
# RESULT-NEXT: noPhis: false
# RESULT-NEXT: isSSA: false
# RESULT-NEXT: noVRegs: false
# RESULT-NEXT: hasFakeUses: true
# RESULT-NEXT: callsEHReturn: true
# RESULT-NEXT: callsUnwindInit: true
# RESULT-NEXT: hasEHCatchret: true
Expand Down Expand Up @@ -47,6 +48,7 @@ hasWinCFI: true
noPhis: false
isSSA: false
noVRegs: false
hasFakeUses: true
failsVerification: true
tracksDebugUserValues: true
callsEHReturn: true
Expand Down
1 change: 1 addition & 0 deletions llvm/tools/llvm-reduce/ReducerWorkItem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ static std::unique_ptr<MachineFunction> cloneMF(MachineFunction *SrcMF,
DstMF->setHasEHCatchret(SrcMF->hasEHCatchret());
DstMF->setHasEHScopes(SrcMF->hasEHScopes());
DstMF->setHasEHFunclets(SrcMF->hasEHFunclets());
DstMF->setHasFakeUses(SrcMF->hasFakeUses());
DstMF->setIsOutlined(SrcMF->isOutlined());

if (!SrcMF->getLandingPads().empty() ||
Expand Down
Loading