LLVM 24.0.0git
HexagonLowerHLXPairAllocas.cpp
Go to the documentation of this file.
1//===- HexagonLowerHLXPairAllocas.cpp - Lower HLX pair allocas ------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// HLX pair registers are interleaved, so a plain load or store of an HLX
10// VectorPair is not two HLX vector memory accesses. Clang only creates pair
11// memory for compiler-generated allocas (e.g. -O0 locals); rewrite the
12// accesses to those allocas that survive optimization into the LL16b.tmp and
13// SS16b.new intrinsics, which define the in-memory layout of a pair.
14//
15//===----------------------------------------------------------------------===//
16
17#include "Hexagon.h"
18#include "HexagonSubtarget.h"
21#include "llvm/IR/IRBuilder.h"
24#include "llvm/IR/IntrinsicsHexagon.h"
26#include "llvm/Pass.h"
27
28using namespace llvm;
29
30#define DEBUG_TYPE "hexagon-lower-hlx-pair-allocas"
31
32namespace {
33
34class HexagonLowerHLXPairAllocas : public FunctionPass {
35public:
36 static char ID;
37
38 HexagonLowerHLXPairAllocas() : FunctionPass(ID) {}
39
40 StringRef getPassName() const override {
41 return "Hexagon Lower HLX Pair Allocas";
42 }
43
44 bool runOnFunction(Function &F) override;
45
46 void getAnalysisUsage(AnalysisUsage &AU) const override {
47 AU.setPreservesCFG();
50 }
51};
52
53} // end anonymous namespace
54
55char HexagonLowerHLXPairAllocas::ID = 0;
56
57INITIALIZE_PASS_BEGIN(HexagonLowerHLXPairAllocas, DEBUG_TYPE,
58 "Hexagon Lower HLX Pair Allocas", false, false)
60INITIALIZE_PASS_END(HexagonLowerHLXPairAllocas, DEBUG_TYPE,
61 "Hexagon Lower HLX Pair Allocas", false, false)
62
63// Return the alloca accessed by I if I is a simple, aligned, temporal load or
64// store of PairTy directly from a PairTy alloca.
66 unsigned VectorLength) {
68 I.isVolatile() || I.isAtomic() ||
69 I.getMetadata(LLVMContext::MD_nontemporal) ||
70 getLoadStoreAlignment(&I).value() < VectorLength)
71 return nullptr;
72 auto *AI = dyn_cast<AllocaInst>(
73 getLoadStorePointerOperand(&I)->stripPointerCastsSameRepresentation());
74 if (!AI || AI->getAllocatedType() != PairTy ||
75 AI->getAlign().value() < VectorLength)
76 return nullptr;
77 return AI;
78}
79
80bool HexagonLowerHLXPairAllocas::runOnFunction(Function &F) {
81 auto &TM = getAnalysis<TargetPassConfig>().getTM<HexagonTargetMachine>();
82 const HexagonSubtarget *HST = TM.getSubtargetImpl(F);
83 if (!HST->useHLXOps())
84 return false;
85
86 unsigned VectorLength = HST->getHLXVectorLength();
87 // Only the i32 VectorPair type is lowered; other HLX types are rejected or
88 // handled by ISel.
89 Type *PairTy =
90 FixedVectorType::get(Type::getInt32Ty(F.getContext()), VectorLength / 2);
91 bool Changed = false;
92 for (Instruction &I : make_early_inc_range(instructions(F))) {
93 AllocaInst *AI = getPairAlloca(I, PairTy, VectorLength);
94 if (!AI)
95 continue;
96
97 IRBuilder<> Builder(&I);
98 CallInst *Call;
99 if (auto *SI = dyn_cast<StoreInst>(&I)) {
100 Call = Builder.CreateCall(
102 Intrinsic::hexagon_LX_SS16b_new),
103 {AI, SI->getValueOperand()});
104 } else {
105 Call = Builder.CreateCall(
107 Intrinsic::hexagon_LX_LL16b_tmp),
108 AI);
110 }
111 Call->setAAMetadata(I.getAAMetadata());
112 Call->copyMetadata(I, {LLVMContext::MD_access_group});
113 I.eraseFromParent();
114 Changed = true;
115 }
116 return Changed;
117}
118
120 return new HexagonLowerHLXPairAllocas();
121}
Expand Atomic instructions
static bool runOnFunction(Function &F, bool PostInlining)
#define DEBUG_TYPE
Hexagon Lower HLX Pair static false AllocaInst * getPairAlloca(Instruction &I, Type *PairTy, unsigned VectorLength)
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
std::pair< MCSymbol *, MachineModuleInfoImpl::StubValueTy > PairTy
#define INITIALIZE_PASS_DEPENDENCY(depName)
Definition PassSupport.h:42
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
Definition PassSupport.h:44
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Definition PassSupport.h:39
Target-Independent Code Generator Pass Configuration Options pass.
an instruction to allocate memory on the stack
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
LLVM_ABI void setPreservesCFG()
This function should be called by the pass, iff they do not:
Definition Pass.cpp:280
static LLVM_ABI FixedVectorType * get(Type *ElementType, unsigned NumElts)
Definition Type.cpp:843
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
LLVM_ABI void setAAMetadata(const AAMDNodes &N)
Sets the AA metadata on this instruction from the AAMDNodes structure.
LLVM_ABI void copyMetadata(const Instruction &SrcInst, ArrayRef< unsigned > WL=ArrayRef< unsigned >())
Copy metadata from SrcInst to this instruction.
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
Definition Pass.cpp:114
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Target-Independent Code Generator Pass Configuration Options.
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
LLVM_ABI void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
Definition Value.cpp:548
CallInst * Call
LLVM_ABI Function * getOrInsertDeclaration(Module *M, ID id, ArrayRef< Type * > OverloadTys={})
Look up the Function declaration of the intrinsic id in the Module M.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createHexagonLowerHLXPairAllocas()
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
const Value * getLoadStorePointerOperand(const Value *V)
A helper function that returns the pointer operand of a load or store instruction.
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
Definition STLExtras.h:649
Align getLoadStoreAlignment(const Value *I)
A helper function that returns the alignment of load or store instruction.
IRBuilder(LLVMContext &, FolderTy, InserterTy) -> IRBuilder< FolderTy, InserterTy >
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
Type * getLoadStoreType(const Value *I)
A helper function that returns the type of a load or store instruction.