[llvm] d826b0c - [LLVM] Add HasFakeUses to MachineFunction (#110097)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Oct 4 05:13:34 PDT 2024
Author: Stephen Tozer
Date: 2024-10-04T13:13:30+01:00
New Revision: d826b0c90f0b0ebebd2b7ed37bf6ff71b34360c8
URL: https://github.com/llvm/llvm-project/commit/d826b0c90f0b0ebebd2b7ed37bf6ff71b34360c8
DIFF: https://github.com/llvm/llvm-project/commit/d826b0c90f0b0ebebd2b7ed37bf6ff71b34360c8.diff
LOG: [LLVM] Add HasFakeUses to MachineFunction (#110097)
Following the addition of the llvm.fake.use intrinsic and corresponding
MIR instruction, two further changes are planned: to add an
-fextend-lifetimes flag to Clang that emits these intrinsics, and to
have -Og enable this flag by default. Currently, some logic for handling
fake uses is gated by the optdebug attribute, which is intended to be
switched on by -fextend-lifetimes (and by extension -Og later on).
However, the decision was made that a general optdebug attribute should
be incompatible with other opt_ attributes (e.g. optsize, optnone),
since they all express different intents for how to optimize the
program. We would still like to allow -fextend-lifetimes with optsize
however (i.e. -Os -fextend-lifetimes should be legal), since it may be a
useful configuration and there is no technical reason to not allow it.
This patch resolves this by tracking MachineFunctions that have fake
uses, allowing us to run passes that interact with them and skip passes
that clash with them.
Added:
llvm/test/CodeGen/MIR/Generic/machine-function-hasfakeuses-conflict.mir
Modified:
llvm/include/llvm/CodeGen/MIRYamlMapping.h
llvm/include/llvm/CodeGen/MachineFunction.h
llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
llvm/lib/CodeGen/MIRParser/MIRParser.cpp
llvm/lib/CodeGen/MIRPrinter.cpp
llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
llvm/test/CodeGen/MIR/Generic/machine-function-optionally-computed-properties.mir
llvm/test/tools/llvm-reduce/mir/preserve-func-info.mir
llvm/tools/llvm-reduce/ReducerWorkItem.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/MIRYamlMapping.h b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
index ab8dc442e04b7b..c5bf6971df4535 100644
--- a/llvm/include/llvm/CodeGen/MIRYamlMapping.h
+++ b/llvm/include/llvm/CodeGen/MIRYamlMapping.h
@@ -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;
@@ -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);
diff --git a/llvm/include/llvm/CodeGen/MachineFunction.h b/llvm/include/llvm/CodeGen/MachineFunction.h
index 997960fcd5d094..49a1fc1f9b7e6d 100644
--- a/llvm/include/llvm/CodeGen/MachineFunction.h
+++ b/llvm/include/llvm/CodeGen/MachineFunction.h
@@ -187,6 +187,7 @@ class MachineFunctionProperties {
TiedOpsRewritten,
FailsVerification,
TracksDebugUserValues,
+ HasFakeUses,
LastProperty = TracksDebugUserValues,
};
@@ -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.
@@ -1195,6 +1197,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; }
diff --git a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
index 40360b0b0f1d86..932287d1403021 100644
--- a/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
+++ b/llvm/lib/CodeGen/GlobalISel/IRTranslator.cpp
@@ -2201,6 +2201,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: {
diff --git a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
index 997c428ca77dc4..30b1a717caaab9 100644
--- a/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
+++ b/llvm/lib/CodeGen/MIRParser/MIRParser.cpp
@@ -380,6 +380,7 @@ 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) {
@@ -387,6 +388,8 @@ bool MIRParserImpl::computeFunctionProperties(
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())
@@ -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;
}
diff --git a/llvm/lib/CodeGen/MIRPrinter.cpp b/llvm/lib/CodeGen/MIRPrinter.cpp
index cf6122bce22364..d52c1d831267f6 100644
--- a/llvm/lib/CodeGen/MIRPrinter.cpp
+++ b/llvm/lib/CodeGen/MIRPrinter.cpp
@@ -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();
diff --git a/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp b/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
index 232181a199b8c2..ef7a58670c3ac5 100644
--- a/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
+++ b/llvm/lib/CodeGen/RemoveLoadsIntoFakeUses.cpp
@@ -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;
diff --git a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
index 8405ba9ac326cf..6a6bc19314d5b6 100644
--- a/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
+++ b/llvm/lib/CodeGen/SelectionDAG/FunctionLoweringInfo.cpp
@@ -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"
@@ -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
diff --git a/llvm/test/CodeGen/MIR/Generic/machine-function-hasfakeuses-conflict.mir b/llvm/test/CodeGen/MIR/Generic/machine-function-hasfakeuses-conflict.mir
new file mode 100644
index 00000000000000..56175bd8bad6ac
--- /dev/null
+++ b/llvm/test/CodeGen/MIR/Generic/machine-function-hasfakeuses-conflict.mir
@@ -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
+...
diff --git a/llvm/test/CodeGen/MIR/Generic/machine-function-optionally-computed-properties.mir b/llvm/test/CodeGen/MIR/Generic/machine-function-optionally-computed-properties.mir
index 858bbc8394bb34..8ac6b2e6ecafdd 100644
--- a/llvm/test/CodeGen/MIR/Generic/machine-function-optionally-computed-properties.mir
+++ b/llvm/test/CodeGen/MIR/Generic/machine-function-optionally-computed-properties.mir
@@ -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
+...
diff --git a/llvm/test/tools/llvm-reduce/mir/preserve-func-info.mir b/llvm/test/tools/llvm-reduce/mir/preserve-func-info.mir
index f735dfd5cbbf01..cbddf89f3b47bd 100644
--- a/llvm/test/tools/llvm-reduce/mir/preserve-func-info.mir
+++ b/llvm/test/tools/llvm-reduce/mir/preserve-func-info.mir
@@ -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
@@ -47,6 +48,7 @@ hasWinCFI: true
noPhis: false
isSSA: false
noVRegs: false
+hasFakeUses: true
failsVerification: true
tracksDebugUserValues: true
callsEHReturn: true
diff --git a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
index 5409b6dc7459d3..5f6a22cb3a9741 100644
--- a/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
+++ b/llvm/tools/llvm-reduce/ReducerWorkItem.cpp
@@ -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() ||
More information about the llvm-commits
mailing list