Skip to content
Closed
Show file tree
Hide file tree
Changes from 4 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
55 changes: 55 additions & 0 deletions llvm/include/llvm/Analysis/InterestingMemoryOperand.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
//===--------- Definition of the InterestingMemoryOperand class -*- C++
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't wrap this line

//-*------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file defines InterestingMemoryOperand class that is used when getting
// the information of a memory reference instruction.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_ANALYSIS_INTERESTINGMEMORYOPERAND_H
#define LLVM_ANALYSIS_INTERESTINGMEMORYOPERAND_H

#include "llvm/IR/DataLayout.h"
#include "llvm/IR/Instruction.h"
#include "llvm/Support/TypeSize.h"

namespace llvm {
class InterestingMemoryOperand {
public:
Use *PtrUse;
bool IsWrite;
Type *OpType;
TypeSize TypeStoreSize = TypeSize::getFixed(0);
MaybeAlign Alignment;
// The mask Value, if we're looking at a masked load/store.
Value *MaybeMask;
// The EVL Value, if we're looking at a vp intrinsic.
Value *MaybeEVL;
// The Stride Value, if we're looking at a strided load/store.
Value *MaybeStride;

InterestingMemoryOperand(Instruction *I, unsigned OperandNo, bool IsWrite,
class Type *OpType, MaybeAlign Alignment,
Value *MaybeMask = nullptr,
Value *MaybeEVL = nullptr,
Value *MaybeStride = nullptr)
: IsWrite(IsWrite), OpType(OpType), Alignment(Alignment),
MaybeMask(MaybeMask), MaybeEVL(MaybeEVL), MaybeStride(MaybeStride) {
const DataLayout &DL = I->getDataLayout();
TypeStoreSize = DL.getTypeStoreSizeInBits(OpType);
PtrUse = &I->getOperandUse(OperandNo);
}

Instruction *getInsn() { return cast<Instruction>(PtrUse->getUser()); }

Value *getPtr() { return PtrUse->get(); }
};

} // namespace llvm
#endif
6 changes: 4 additions & 2 deletions llvm/include/llvm/Analysis/TargetTransformInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
#include "llvm/ADT/APInt.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/Analysis/IVDescriptors.h"
#include "llvm/Analysis/InterestingMemoryOperand.h"
#include "llvm/IR/FMF.h"
#include "llvm/IR/InstrTypes.h"
#include "llvm/IR/PassManager.h"
Expand Down Expand Up @@ -1696,8 +1697,9 @@ class TargetTransformInfo {
/// will contain additional information - whether the intrinsic may write
/// or read to memory, volatility and the pointer. Info is undefined
/// if false is returned.
LLVM_ABI bool getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const;
LLVM_ABI std::pair<std::optional<MemIntrinsicInfo>,
std::optional<SmallVector<InterestingMemoryOperand, 1>>>
getTgtMemIntrinsic(IntrinsicInst *Inst) const;

/// \returns The maximum element size, in bytes, for an element
/// unordered-atomic memory intrinsic.
Expand Down
7 changes: 4 additions & 3 deletions llvm/include/llvm/Analysis/TargetTransformInfoImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -975,9 +975,10 @@ class TargetTransformInfoImplBase {
return 0;
}

virtual bool getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const {
return false;
virtual std::pair<std::optional<MemIntrinsicInfo>,
std::optional<SmallVector<InterestingMemoryOperand, 1>>>
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we need an optional around the SmallVector? Can we use an empty vector to represent no interesting operand?

Looks like EarlyCSE will ignore MemIntrinsicInfo with a null PtrVal. Can we use that instead of an optional?

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think use an empty vector to represent no interesting operand is a great idea, in this way we don't need to use optional for SmallVector.

Use a null PtrVal to check MemIntrinsicInfo might be fine, I just checked the target that uses getTgtMemIntrinsic and find that all of them fill PtrVal and EarlyCSE/LoopStrengthReduce also ignore PtrVal with nullptr.

I will try to modify it with dropping optional.

Copy link
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
std::optional<SmallVector<InterestingMemoryOperand, 1>>>
std::pair<MemIntrinsicInfo,
SmallVector<InterestingMemoryOperand, 1>>

The interface after dropping std::optional will look like this.

getTgtMemIntrinsic(IntrinsicInst *Inst) const {
return std::make_pair(std::nullopt, std::nullopt);
}

virtual unsigned getAtomicMemIntrinsicMaxElementSize() const {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,45 +14,14 @@
#define LLVM_TRANSFORMS_INSTRUMENTATION_ADDRESSSANITIZERCOMMON_H

#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/InterestingMemoryOperand.h"
#include "llvm/Analysis/PostDominators.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/IntrinsicInst.h"
#include "llvm/IR/Module.h"

namespace llvm {

class InterestingMemoryOperand {
public:
Use *PtrUse;
bool IsWrite;
Type *OpType;
TypeSize TypeStoreSize = TypeSize::getFixed(0);
MaybeAlign Alignment;
// The mask Value, if we're looking at a masked load/store.
Value *MaybeMask;
// The EVL Value, if we're looking at a vp intrinsic.
Value *MaybeEVL;
// The Stride Value, if we're looking at a strided load/store.
Value *MaybeStride;

InterestingMemoryOperand(Instruction *I, unsigned OperandNo, bool IsWrite,
class Type *OpType, MaybeAlign Alignment,
Value *MaybeMask = nullptr,
Value *MaybeEVL = nullptr,
Value *MaybeStride = nullptr)
: IsWrite(IsWrite), OpType(OpType), Alignment(Alignment),
MaybeMask(MaybeMask), MaybeEVL(MaybeEVL), MaybeStride(MaybeStride) {
const DataLayout &DL = I->getDataLayout();
TypeStoreSize = DL.getTypeStoreSizeInBits(OpType);
PtrUse = &I->getOperandUse(OperandNo);
}

Instruction *getInsn() { return cast<Instruction>(PtrUse->getUser()); }

Value *getPtr() { return PtrUse->get(); }
};

// Get AddressSanitizer parameters.
void getAddressSanitizerParams(const Triple &TargetTriple, int LongSize,
bool IsKasan, uint64_t *ShadowBase,
Expand Down
8 changes: 5 additions & 3 deletions llvm/lib/Analysis/TargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
//===----------------------------------------------------------------------===//

#include "llvm/Analysis/TargetTransformInfo.h"
#include "llvm/ADT/SmallVector.h"
#include "llvm/Analysis/CFG.h"
#include "llvm/Analysis/LoopIterator.h"
#include "llvm/Analysis/TargetLibraryInfo.h"
Expand Down Expand Up @@ -1285,9 +1286,10 @@ TargetTransformInfo::getCostOfKeepingLiveOverCall(ArrayRef<Type *> Tys) const {
return TTIImpl->getCostOfKeepingLiveOverCall(Tys);
}

bool TargetTransformInfo::getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const {
return TTIImpl->getTgtMemIntrinsic(Inst, Info);
std::pair<std::optional<MemIntrinsicInfo>,
std::optional<SmallVector<InterestingMemoryOperand, 1>>>
TargetTransformInfo::getTgtMemIntrinsic(IntrinsicInst *Inst) const {
return TTIImpl->getTgtMemIntrinsic(Inst);
}

unsigned TargetTransformInfo::getAtomicMemIntrinsicMaxElementSize() const {
Expand Down
10 changes: 6 additions & 4 deletions llvm/lib/Target/AArch64/AArch64TargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5125,8 +5125,10 @@ Value *AArch64TTIImpl::getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst,
}
}

bool AArch64TTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const {
std::pair<std::optional<MemIntrinsicInfo>,
std::optional<SmallVector<InterestingMemoryOperand, 1>>>
AArch64TTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst) const {
MemIntrinsicInfo Info;
switch (Inst->getIntrinsicID()) {
default:
break;
Expand All @@ -5148,7 +5150,7 @@ bool AArch64TTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,

switch (Inst->getIntrinsicID()) {
default:
return false;
return std::make_pair(std::nullopt, std::nullopt);
case Intrinsic::aarch64_neon_ld2:
case Intrinsic::aarch64_neon_st2:
Info.MatchingId = VECTOR_LDST_TWO_ELEMENTS;
Expand All @@ -5162,7 +5164,7 @@ bool AArch64TTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
Info.MatchingId = VECTOR_LDST_FOUR_ELEMENTS;
break;
}
return true;
return std::make_pair(Info, std::nullopt);
}

/// See if \p I should be considered for address type promotion. We check if \p
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/AArch64/AArch64TargetTransformInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,9 @@ class AArch64TTIImpl final : public BasicTTIImplBase<AArch64TTIImpl> {
getOrCreateResultFromMemIntrinsic(IntrinsicInst *Inst, Type *ExpectedType,
bool CanCreate = true) const override;

bool getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const override;
std::pair<std::optional<MemIntrinsicInfo>,
std::optional<SmallVector<InterestingMemoryOperand, 1>>>
getTgtMemIntrinsic(IntrinsicInst *Inst) const override;

bool isElementTypeLegalForScalableVector(Type *Ty) const override {
if (Ty->isPointerTy())
Expand Down
17 changes: 10 additions & 7 deletions llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,29 +500,32 @@ unsigned GCNTTIImpl::getMaxInterleaveFactor(ElementCount VF) const {
return 8;
}

bool GCNTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const {
std::pair<std::optional<MemIntrinsicInfo>,
std::optional<SmallVector<InterestingMemoryOperand, 1>>>
GCNTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst) const {
switch (Inst->getIntrinsicID()) {
case Intrinsic::amdgcn_ds_ordered_add:
case Intrinsic::amdgcn_ds_ordered_swap: {
auto *Ordering = dyn_cast<ConstantInt>(Inst->getArgOperand(2));
auto *Volatile = dyn_cast<ConstantInt>(Inst->getArgOperand(4));
if (!Ordering || !Volatile)
return false; // Invalid.
return std::make_pair(std::nullopt, std::nullopt); // Invalid

unsigned OrderingVal = Ordering->getZExtValue();
if (OrderingVal > static_cast<unsigned>(AtomicOrdering::SequentiallyConsistent))
return false;
if (OrderingVal >
static_cast<unsigned>(AtomicOrdering::SequentiallyConsistent))
return std::make_pair(std::nullopt, std::nullopt);

MemIntrinsicInfo Info;
Info.PtrVal = Inst->getArgOperand(0);
Info.Ordering = static_cast<AtomicOrdering>(OrderingVal);
Info.ReadMem = true;
Info.WriteMem = true;
Info.IsVolatile = !Volatile->isZero();
return true;
return std::make_pair(Info, std::nullopt);
}
default:
return false;
return std::make_pair(std::nullopt, std::nullopt);
}
}

Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/AMDGPU/AMDGPUTargetTransformInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -151,8 +151,9 @@ class GCNTTIImpl final : public BasicTTIImplBase<GCNTTIImpl> {
std::optional<uint32_t> AtomicCpySize) const override;
unsigned getMaxInterleaveFactor(ElementCount VF) const override;

bool getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const override;
std::pair<std::optional<MemIntrinsicInfo>,
std::optional<SmallVector<InterestingMemoryOperand, 1>>>
getTgtMemIntrinsic(IntrinsicInst *Inst) const override;

InstructionCost getArithmeticInstrCost(
unsigned Opcode, Type *Ty, TTI::TargetCostKind CostKind,
Expand Down
15 changes: 8 additions & 7 deletions llvm/lib/Target/PowerPC/PPCTargetTransformInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -975,8 +975,10 @@ bool PPCTTIImpl::shouldBuildRelLookupTables() const {
return BaseT::shouldBuildRelLookupTables();
}

bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const {
std::pair<std::optional<MemIntrinsicInfo>,
std::optional<SmallVector<InterestingMemoryOperand, 1>>>
PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst) const {
MemIntrinsicInfo Info;
switch (Inst->getIntrinsicID()) {
case Intrinsic::ppc_altivec_lvx:
case Intrinsic::ppc_altivec_lvxl:
Expand All @@ -993,7 +995,7 @@ bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
Info.PtrVal = Inst->getArgOperand(0);
Info.ReadMem = true;
Info.WriteMem = false;
return true;
return std::make_pair(Info, std::nullopt);
}
case Intrinsic::ppc_altivec_stvx:
case Intrinsic::ppc_altivec_stvxl:
Expand All @@ -1010,7 +1012,7 @@ bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
Info.PtrVal = Inst->getArgOperand(1);
Info.ReadMem = false;
Info.WriteMem = true;
return true;
return std::make_pair(Info, std::nullopt);
}
case Intrinsic::ppc_stbcx:
case Intrinsic::ppc_sthcx:
Expand All @@ -1019,13 +1021,12 @@ bool PPCTTIImpl::getTgtMemIntrinsic(IntrinsicInst *Inst,
Info.PtrVal = Inst->getArgOperand(0);
Info.ReadMem = false;
Info.WriteMem = true;
return true;
return std::make_pair(Info, std::nullopt);
}
default:
break;
}

return false;
return std::make_pair(std::nullopt, std::nullopt);
}

bool PPCTTIImpl::supportsTailCallFor(const CallBase *CB) const {
Expand Down
5 changes: 3 additions & 2 deletions llvm/lib/Target/PowerPC/PPCTargetTransformInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,9 @@ class PPCTTIImpl final : public BasicTTIImplBase<PPCTTIImpl> {
bool canSaveCmp(Loop *L, BranchInst **BI, ScalarEvolution *SE, LoopInfo *LI,
DominatorTree *DT, AssumptionCache *AC,
TargetLibraryInfo *LibInfo) const override;
bool getTgtMemIntrinsic(IntrinsicInst *Inst,
MemIntrinsicInfo &Info) const override;
std::pair<std::optional<MemIntrinsicInfo>,
std::optional<SmallVector<InterestingMemoryOperand, 1>>>
getTgtMemIntrinsic(IntrinsicInst *Inst) const override;
void getUnrollingPreferences(Loop *L, ScalarEvolution &SE,
TTI::UnrollingPreferences &UP,
OptimizationRemarkEmitter *ORE) const override;
Expand Down
Loading