Skip to content

Commit

Permalink
[TableGen] Use MemoryEffects to represent intrinsic memory effects (N…
Browse files Browse the repository at this point in the history
…FCI)

The TableGen implementation was using a homegrown implementation of
FunctionModRefInfo. This switches it to use MemoryEffects instead.
This makes the code simpler, and will allow exposing the full
representational power of MemoryEffects in the future. Among other
things, this will allow us to map IntrHasSideEffects to an
inaccessiblemem readwrite, rather than just ignoring it entirely
in most cases.

To avoid layering issues, this moves the ModRef.h header from IR
to Support, so that it can be included in the TableGen layer.

Differential Revision: https://reviews.llvm.org/D137641
  • Loading branch information
nikic committed Nov 14, 2022
1 parent 49ee563 commit feda983
Show file tree
Hide file tree
Showing 15 changed files with 39 additions and 129 deletions.
2 changes: 1 addition & 1 deletion llvm/include/llvm/Analysis/AliasAnalysis.h
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@
#include "llvm/ADT/Sequence.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/MemoryLocation.h"
#include "llvm/IR/ModRef.h"
#include "llvm/IR/PassManager.h"
#include "llvm/Pass.h"
#include "llvm/Support/ModRef.h"
#include <cstdint>
#include <functional>
#include <memory>
Expand Down
File renamed without changes.
2 changes: 1 addition & 1 deletion llvm/lib/AsmParser/LLParser.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,14 +37,14 @@
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ModRef.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Value.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/SaveAndRestore.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Bitcode/Reader/BitcodeReader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@
#include "llvm/IR/IntrinsicsARM.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ModRef.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ModuleSummaryIndex.h"
#include "llvm/IR/Operator.h"
Expand All @@ -72,6 +71,7 @@
#include "llvm/Support/ErrorOr.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/CodeGen/MachineVerifier.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@
#include "llvm/IR/Function.h"
#include "llvm/IR/InlineAsm.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/ModRef.h"
#include "llvm/InitializePasses.h"
#include "llvm/MC/LaneBitmask.h"
#include "llvm/MC/MCAsmInfo.h"
Expand All @@ -74,6 +73,7 @@
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/LowLevelTypeImpl.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"
#include <algorithm>
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/Attributes.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,10 @@
#include "llvm/Config/llvm-config.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/ModRef.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <cassert>
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/Function.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ModRef.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/SymbolTableListTraits.h"
Expand All @@ -64,6 +63,7 @@
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/Compiler.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/ModRef.h"
#include <cassert>
#include <cstddef>
#include <cstdint>
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/IR/Instructions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/MDBuilder.h"
#include "llvm/IR/Metadata.h"
#include "llvm/IR/ModRef.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Operator.h"
#include "llvm/IR/Type.h"
Expand All @@ -39,6 +38,7 @@
#include "llvm/Support/Casting.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MathExtras.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/TypeSize.h"
#include <algorithm>
#include <cassert>
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/AMDGPU/AMDGPULibFunc.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
#include "llvm/ADT/StringSwitch.h"
#include "llvm/IR/DerivedTypes.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/ModRef.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/ValueSymbolTable.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/raw_ostream.h"

using namespace llvm;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/AMDGPU/SIISelLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,8 +34,8 @@
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/IntrinsicsAMDGPU.h"
#include "llvm/IR/IntrinsicsR600.h"
#include "llvm/IR/ModRef.h"
#include "llvm/Support/CommandLine.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/KnownBits.h"

using namespace llvm;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/Mips/Mips16HardFloat.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@

#include "MipsTargetMachine.h"
#include "llvm/CodeGen/TargetPassConfig.h"
#include "llvm/IR/ModRef.h"
#include "llvm/IR/Module.h"
#include "llvm/IR/Value.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ModRef.h"
#include "llvm/Support/raw_ostream.h"
#include <algorithm>
#include <string>
Expand Down
17 changes: 9 additions & 8 deletions llvm/utils/TableGen/CodeGenDAGPatterns.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2998,7 +2998,7 @@ TreePatternNodePtr TreePattern::ParseTreePattern(Init *TheInit,
// chain.
if (Int.IS.RetVTs.empty())
Operator = getDAGPatterns().get_intrinsic_void_sdnode();
else if (Int.ModRef != CodeGenIntrinsic::NoMem || Int.hasSideEffects)
else if (!Int.ME.doesNotAccessMemory() || Int.hasSideEffects)
// Has side-effects, requires chain.
Operator = getDAGPatterns().get_intrinsic_w_chain_sdnode();
else // Otherwise, no chain.
Expand Down Expand Up @@ -3637,16 +3637,17 @@ class InstAnalyzer {
if (N->NodeHasProperty(SDNPHasChain, CDP)) hasChain = true;

if (const CodeGenIntrinsic *IntInfo = N->getIntrinsicInfo(CDP)) {
ModRefInfo MR = IntInfo->ME.getModRef();
// If this is an intrinsic, analyze it.
if (IntInfo->ModRef & CodeGenIntrinsic::MR_Ref)
mayLoad = true;// These may load memory.
if (isRefSet(MR))
mayLoad = true; // These may load memory.

if (IntInfo->ModRef & CodeGenIntrinsic::MR_Mod)
mayStore = true;// Intrinsics that can write to memory are 'mayStore'.
if (isModSet(MR))
mayStore = true; // Intrinsics that can write to memory are 'mayStore'.

if (IntInfo->ModRef >= CodeGenIntrinsic::ReadWriteMem ||
IntInfo->hasSideEffects)
// ReadWriteMem intrinsics can have other strange effects.
// Consider intrinsics that don't specify any restrictions on memory
// effects as having a side-effect.
if (IntInfo->ME == MemoryEffects::unknown() || IntInfo->hasSideEffects)
hasSideEffects = true;
}
}
Expand Down
48 changes: 3 additions & 45 deletions llvm/utils/TableGen/CodeGenIntrinsics.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include "SDNodeProperties.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Support/MachineValueType.h"
#include "llvm/Support/ModRef.h"
#include <string>
#include <vector>

Expand Down Expand Up @@ -58,51 +59,8 @@ struct CodeGenIntrinsic {

IntrinsicSignature IS;

/// Bit flags describing the type (ref/mod) and location of memory
/// accesses that may be performed by the intrinsics. Analogous to
/// \c FunctionModRefBehaviour.
enum ModRefBits {
/// The intrinsic may access memory that is otherwise inaccessible via
/// LLVM IR.
MR_InaccessibleMem = 1,

/// The intrinsic may access memory through pointer arguments.
/// LLVM IR.
MR_ArgMem = 2,

/// The intrinsic may access memory anywhere, i.e. it is not restricted
/// to access through pointer arguments.
MR_Anywhere = 4 | MR_ArgMem | MR_InaccessibleMem,

/// The intrinsic may read memory.
MR_Ref = 8,

/// The intrinsic may write memory.
MR_Mod = 16,

/// The intrinsic may both read and write memory.
MR_ModRef = MR_Ref | MR_Mod,
};

/// Memory mod/ref behavior of this intrinsic, corresponding to intrinsic
/// properties (IntrReadMem, IntrArgMemOnly, etc.).
enum ModRefBehavior {
NoMem = 0,
ReadArgMem = MR_Ref | MR_ArgMem,
ReadInaccessibleMem = MR_Ref | MR_InaccessibleMem,
ReadInaccessibleMemOrArgMem = MR_Ref | MR_ArgMem | MR_InaccessibleMem,
ReadMem = MR_Ref | MR_Anywhere,
WriteArgMem = MR_Mod | MR_ArgMem,
WriteInaccessibleMem = MR_Mod | MR_InaccessibleMem,
WriteInaccessibleMemOrArgMem = MR_Mod | MR_ArgMem | MR_InaccessibleMem,
WriteMem = MR_Mod | MR_Anywhere,
ReadWriteArgMem = MR_ModRef | MR_ArgMem,
ReadWriteInaccessibleMem = MR_ModRef | MR_InaccessibleMem,
ReadWriteInaccessibleMemOrArgMem = MR_ModRef | MR_ArgMem |
MR_InaccessibleMem,
ReadWriteMem = MR_ModRef | MR_Anywhere,
};
ModRefBehavior ModRef;
/// Memory effects of the intrinsic.
MemoryEffects ME = MemoryEffects::unknown();

/// SDPatternOperator Properties applied to the intrinsic.
unsigned Properties;
Expand Down
18 changes: 8 additions & 10 deletions llvm/utils/TableGen/CodeGenTarget.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -668,7 +668,6 @@ CodeGenIntrinsic::CodeGenIntrinsic(Record *R,
TheDef = R;
std::string DefName = std::string(R->getName());
ArrayRef<SMLoc> DefLoc = R->getLoc();
ModRef = ReadWriteMem;
Properties = 0;
isOverloaded = false;
isCommutative = false;
Expand Down Expand Up @@ -842,26 +841,25 @@ void CodeGenIntrinsic::setDefaultProperties(

void CodeGenIntrinsic::setProperty(Record *R) {
if (R->getName() == "IntrNoMem")
ModRef = NoMem;
ME = MemoryEffects::none();
else if (R->getName() == "IntrReadMem") {
if (!(ModRef & MR_Ref))
if (ME.onlyWritesMemory())
PrintFatalError(TheDef->getLoc(),
Twine("IntrReadMem cannot be used after IntrNoMem or "
"IntrWriteMem. Default is ReadWrite"));
ModRef = ModRefBehavior(ModRef & ~MR_Mod);
ME &= MemoryEffects::readOnly();
} else if (R->getName() == "IntrWriteMem") {
if (!(ModRef & MR_Mod))
if (ME.onlyReadsMemory())
PrintFatalError(TheDef->getLoc(),
Twine("IntrWriteMem cannot be used after IntrNoMem or "
"IntrReadMem. Default is ReadWrite"));
ModRef = ModRefBehavior(ModRef & ~MR_Ref);
ME &= MemoryEffects::writeOnly();
} else if (R->getName() == "IntrArgMemOnly")
ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_ArgMem);
ME &= MemoryEffects::argMemOnly();
else if (R->getName() == "IntrInaccessibleMemOnly")
ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_InaccessibleMem);
ME &= MemoryEffects::inaccessibleMemOnly();
else if (R->getName() == "IntrInaccessibleMemOrArgMemOnly")
ModRef = ModRefBehavior((ModRef & ~MR_Anywhere) | MR_ArgMem |
MR_InaccessibleMem);
ME &= MemoryEffects::inaccessibleOrArgMemOnly();
else if (R->getName() == "Commutative")
isCommutative = true;
else if (R->getName() == "Throws")
Expand Down
65 changes: 9 additions & 56 deletions llvm/utils/TableGen/IntrinsicEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,8 +642,8 @@ Optional<bool> compareFnAttributes(const CodeGenIntrinsic *L,
return R->hasSideEffects;

// Try to order by readonly/readnone attribute.
CodeGenIntrinsic::ModRefBehavior LK = L->ModRef;
CodeGenIntrinsic::ModRefBehavior RK = R->ModRef;
uint32_t LK = L->ME.toIntValue();
uint32_t RK = R->ME.toIntValue();
if (LK != RK) return (LK > RK);

return None;
Expand Down Expand Up @@ -772,60 +772,13 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints,
if (Intrinsic.isSpeculatable)
OS << " Attribute::get(C, Attribute::Speculatable),\n";

switch (Intrinsic.ModRef) {
case CodeGenIntrinsic::NoMem:
if (Intrinsic.hasSideEffects)
break;
MemoryEffects ME = Intrinsic.ME;
// TODO: IntrHasSideEffects should affect not only readnone intrinsics.
if (ME.doesNotAccessMemory() && Intrinsic.hasSideEffects)
ME = MemoryEffects::unknown();
if (ME != MemoryEffects::unknown()) {
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::none()),\n";
break;
case CodeGenIntrinsic::ReadArgMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::argMemOnly(ModRefInfo::Ref)),\n";
break;
case CodeGenIntrinsic::ReadMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::readOnly()),\n";
break;
case CodeGenIntrinsic::ReadInaccessibleMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::inaccessibleMemOnly(ModRefInfo::Ref)),\n";
break;
case CodeGenIntrinsic::ReadInaccessibleMemOrArgMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::inaccessibleOrArgMemOnly(ModRefInfo::Ref)),\n";
break;
break;
case CodeGenIntrinsic::WriteArgMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::argMemOnly(ModRefInfo::Mod)),\n";
break;
case CodeGenIntrinsic::WriteMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::writeOnly()),\n";
break;
case CodeGenIntrinsic::WriteInaccessibleMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::inaccessibleMemOnly(ModRefInfo::Mod)),\n";
break;
case CodeGenIntrinsic::WriteInaccessibleMemOrArgMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::inaccessibleOrArgMemOnly(ModRefInfo::Mod)),\n";
break;
case CodeGenIntrinsic::ReadWriteArgMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::argMemOnly(ModRefInfo::ModRef)),\n";
break;
case CodeGenIntrinsic::ReadWriteInaccessibleMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::inaccessibleMemOnly(ModRefInfo::ModRef)),\n";
break;
case CodeGenIntrinsic::ReadWriteInaccessibleMemOrArgMem:
OS << " Attribute::getWithMemoryEffects(C, "
<< "MemoryEffects::inaccessibleOrArgMemOnly(ModRefInfo::ModRef)),\n";
break;
case CodeGenIntrinsic::ReadWriteMem:
break;
<< "MemoryEffects::createFromIntValue(" << ME.toIntValue() << ")),\n";
}
OS << " });\n";
}
Expand Down Expand Up @@ -885,7 +838,7 @@ void IntrinsicEmitter::EmitAttributes(const CodeGenIntrinsicTable &Ints,
}

if (!Intrinsic.canThrow ||
(Intrinsic.ModRef != CodeGenIntrinsic::ReadWriteMem &&
(Intrinsic.ME != MemoryEffects::unknown() &&
!Intrinsic.hasSideEffects) ||
Intrinsic.isNoReturn || Intrinsic.isNoCallback || Intrinsic.isNoSync ||
Intrinsic.isNoFree || Intrinsic.isWillReturn || Intrinsic.isCold ||
Expand Down

0 comments on commit feda983

Please sign in to comment.