003 File Manager
Current Path:
/usr/src/contrib/llvm-project/llvm/lib/Target/Hexagon
usr
/
src
/
contrib
/
llvm-project
/
llvm
/
lib
/
Target
/
Hexagon
/
📁
..
📁
AsmParser
📄
BitTracker.cpp
(35.36 KB)
📄
BitTracker.h
(17.25 KB)
📁
Disassembler
📄
Hexagon.h
(1004 B)
📄
Hexagon.td
(17.33 KB)
📄
HexagonArch.h
(1.2 KB)
📄
HexagonAsmPrinter.cpp
(26.65 KB)
📄
HexagonAsmPrinter.h
(2.03 KB)
📄
HexagonBitSimplify.cpp
(107.45 KB)
📄
HexagonBitTracker.cpp
(39.88 KB)
📄
HexagonBitTracker.h
(2.5 KB)
📄
HexagonBlockRanges.cpp
(15.85 KB)
📄
HexagonBlockRanges.h
(6.97 KB)
📄
HexagonBranchRelaxation.cpp
(7.78 KB)
📄
HexagonCFGOptimizer.cpp
(8.4 KB)
📄
HexagonCallingConv.td
(4.46 KB)
📄
HexagonCommonGEP.cpp
(41.47 KB)
📄
HexagonConstExtenders.cpp
(70.64 KB)
📄
HexagonConstPropagation.cpp
(97.75 KB)
📄
HexagonCopyToCombine.cpp
(32.2 KB)
📄
HexagonDepArch.h
(2.04 KB)
📄
HexagonDepArch.td
(1.87 KB)
📄
HexagonDepDecoders.inc
(2.55 KB)
📄
HexagonDepIICHVX.td
(113.05 KB)
📄
HexagonDepIICScalar.td
(224.12 KB)
📄
HexagonDepITypes.h
(1.51 KB)
📄
HexagonDepITypes.td
(1.91 KB)
📄
HexagonDepInstrFormats.td
(91.89 KB)
📄
HexagonDepInstrInfo.td
(1021.44 KB)
📄
HexagonDepMapAsm2Intrin.td
(255.17 KB)
📄
HexagonDepMappings.td
(64.27 KB)
📄
HexagonDepMask.h
(51.94 KB)
📄
HexagonDepOperands.td
(12.12 KB)
📄
HexagonDepTimingClasses.h
(4.69 KB)
📄
HexagonEarlyIfConv.cpp
(37.36 KB)
📄
HexagonExpandCondsets.cpp
(48.55 KB)
📄
HexagonFixupHwLoops.cpp
(6.54 KB)
📄
HexagonFrameLowering.cpp
(97.16 KB)
📄
HexagonFrameLowering.h
(7.85 KB)
📄
HexagonGenExtract.cpp
(8.61 KB)
📄
HexagonGenInsert.cpp
(53.24 KB)
📄
HexagonGenMux.cpp
(12.71 KB)
📄
HexagonGenPredicate.cpp
(16.25 KB)
📄
HexagonHardwareLoops.cpp
(70.32 KB)
📄
HexagonHazardRecognizer.cpp
(5.85 KB)
📄
HexagonHazardRecognizer.h
(3.58 KB)
📄
HexagonIICHVX.td
(1.21 KB)
📄
HexagonIICScalar.td
(1.34 KB)
📄
HexagonISelDAGToDAG.cpp
(78.63 KB)
📄
HexagonISelDAGToDAG.h
(5.88 KB)
📄
HexagonISelDAGToDAGHVX.cpp
(68.26 KB)
📄
HexagonISelLowering.cpp
(134.65 KB)
📄
HexagonISelLowering.h
(22.5 KB)
📄
HexagonISelLoweringHVX.cpp
(70.57 KB)
📄
HexagonInstrFormats.td
(12.04 KB)
📄
HexagonInstrFormatsV60.td
(1.03 KB)
📄
HexagonInstrFormatsV65.td
(1.54 KB)
📄
HexagonInstrInfo.cpp
(161.08 KB)
📄
HexagonInstrInfo.h
(25.31 KB)
📄
HexagonIntrinsics.td
(19.21 KB)
📄
HexagonIntrinsicsV5.td
(16.8 KB)
📄
HexagonIntrinsicsV60.td
(28.9 KB)
📄
HexagonLoopIdiomRecognition.cpp
(79.16 KB)
📄
HexagonMCInstLower.cpp
(6.25 KB)
📄
HexagonMachineFunctionInfo.cpp
(507 B)
📄
HexagonMachineFunctionInfo.h
(3.32 KB)
📄
HexagonMachineScheduler.cpp
(34.25 KB)
📄
HexagonMachineScheduler.h
(8.66 KB)
📄
HexagonMapAsm2IntrinV62.gen.td
(8.71 KB)
📄
HexagonMapAsm2IntrinV65.gen.td
(12.43 KB)
📄
HexagonNewValueJump.cpp
(25.57 KB)
📄
HexagonOperands.td
(1.62 KB)
📄
HexagonOptAddrMode.cpp
(29.37 KB)
📄
HexagonOptimizeSZextends.cpp
(4.74 KB)
📄
HexagonPatterns.td
(142.35 KB)
📄
HexagonPatternsHVX.td
(22.06 KB)
📄
HexagonPatternsV65.td
(2.96 KB)
📄
HexagonPeephole.cpp
(10.18 KB)
📄
HexagonPseudo.td
(21.62 KB)
📄
HexagonRDFOpt.cpp
(9.94 KB)
📄
HexagonRegisterInfo.cpp
(12.03 KB)
📄
HexagonRegisterInfo.h
(2.88 KB)
📄
HexagonRegisterInfo.td
(20.42 KB)
📄
HexagonSchedule.td
(2.33 KB)
📄
HexagonScheduleV5.td
(1.73 KB)
📄
HexagonScheduleV55.td
(1.81 KB)
📄
HexagonScheduleV60.td
(4.31 KB)
📄
HexagonScheduleV62.td
(1.53 KB)
📄
HexagonScheduleV65.td
(1.57 KB)
📄
HexagonScheduleV66.td
(1.57 KB)
📄
HexagonScheduleV67.td
(1.57 KB)
📄
HexagonScheduleV67T.td
(2.51 KB)
📄
HexagonSelectionDAGInfo.cpp
(2.35 KB)
📄
HexagonSelectionDAGInfo.h
(1.24 KB)
📄
HexagonSplitConst32AndConst64.cpp
(4.15 KB)
📄
HexagonSplitDouble.cpp
(37.86 KB)
📄
HexagonStoreWidening.cpp
(20.47 KB)
📄
HexagonSubtarget.cpp
(20.97 KB)
📄
HexagonSubtarget.h
(10.59 KB)
📄
HexagonTargetMachine.cpp
(16 KB)
📄
HexagonTargetMachine.h
(1.77 KB)
📄
HexagonTargetObjectFile.cpp
(16.8 KB)
📄
HexagonTargetObjectFile.h
(2.17 KB)
📄
HexagonTargetStreamer.h
(1.2 KB)
📄
HexagonTargetTransformInfo.cpp
(13.11 KB)
📄
HexagonTargetTransformInfo.h
(6.27 KB)
📄
HexagonVExtract.cpp
(6.64 KB)
📄
HexagonVLIWPacketizer.cpp
(67.01 KB)
📄
HexagonVLIWPacketizer.h
(6.09 KB)
📄
HexagonVectorLoopCarriedReuse.cpp
(23.99 KB)
📄
HexagonVectorPrint.cpp
(7.06 KB)
📁
MCTargetDesc
📄
RDFCopy.cpp
(6.37 KB)
📄
RDFCopy.h
(1.69 KB)
📄
RDFDeadCode.cpp
(7.5 KB)
📄
RDFDeadCode.h
(2.33 KB)
📁
TargetInfo
Editing: HexagonGenExtract.cpp
//===- HexagonGenExtract.cpp ----------------------------------------------===// // // 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 // //===----------------------------------------------------------------------===// #include "llvm/ADT/APInt.h" #include "llvm/ADT/GraphTraits.h" #include "llvm/IR/BasicBlock.h" #include "llvm/IR/CFG.h" #include "llvm/IR/Constants.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Function.h" #include "llvm/IR/IRBuilder.h" #include "llvm/IR/Instruction.h" #include "llvm/IR/Instructions.h" #include "llvm/IR/Intrinsics.h" #include "llvm/IR/IntrinsicsHexagon.h" #include "llvm/IR/PatternMatch.h" #include "llvm/IR/Type.h" #include "llvm/IR/Value.h" #include "llvm/InitializePasses.h" #include "llvm/Pass.h" #include "llvm/Support/CommandLine.h" #include <algorithm> #include <cstdint> #include <iterator> using namespace llvm; static cl::opt<unsigned> ExtractCutoff("extract-cutoff", cl::init(~0U), cl::Hidden, cl::desc("Cutoff for generating \"extract\"" " instructions")); // This prevents generating extract instructions that have the offset of 0. // One of the reasons for "extract" is to put a sequence of bits in a regis- // ter, starting at offset 0 (so that these bits can then be used by an // "insert"). If the bits are already at offset 0, it is better not to gene- // rate "extract", since logical bit operations can be merged into compound // instructions (as opposed to "extract"). static cl::opt<bool> NoSR0("extract-nosr0", cl::init(true), cl::Hidden, cl::desc("No extract instruction with offset 0")); static cl::opt<bool> NeedAnd("extract-needand", cl::init(true), cl::Hidden, cl::desc("Require & in extract patterns")); namespace llvm { void initializeHexagonGenExtractPass(PassRegistry&); FunctionPass *createHexagonGenExtract(); } // end namespace llvm namespace { class HexagonGenExtract : public FunctionPass { public: static char ID; HexagonGenExtract() : FunctionPass(ID) { initializeHexagonGenExtractPass(*PassRegistry::getPassRegistry()); } StringRef getPassName() const override { return "Hexagon generate \"extract\" instructions"; } bool runOnFunction(Function &F) override; void getAnalysisUsage(AnalysisUsage &AU) const override { AU.addRequired<DominatorTreeWrapperPass>(); AU.addPreserved<DominatorTreeWrapperPass>(); FunctionPass::getAnalysisUsage(AU); } private: bool visitBlock(BasicBlock *B); bool convert(Instruction *In); unsigned ExtractCount = 0; DominatorTree *DT; }; } // end anonymous namespace char HexagonGenExtract::ID = 0; INITIALIZE_PASS_BEGIN(HexagonGenExtract, "hextract", "Hexagon generate " "\"extract\" instructions", false, false) INITIALIZE_PASS_DEPENDENCY(DominatorTreeWrapperPass) INITIALIZE_PASS_END(HexagonGenExtract, "hextract", "Hexagon generate " "\"extract\" instructions", false, false) bool HexagonGenExtract::convert(Instruction *In) { using namespace PatternMatch; Value *BF = nullptr; ConstantInt *CSL = nullptr, *CSR = nullptr, *CM = nullptr; BasicBlock *BB = In->getParent(); LLVMContext &Ctx = BB->getContext(); bool LogicalSR; // (and (shl (lshr x, #sr), #sl), #m) LogicalSR = true; bool Match = match(In, m_And(m_Shl(m_LShr(m_Value(BF), m_ConstantInt(CSR)), m_ConstantInt(CSL)), m_ConstantInt(CM))); if (!Match) { // (and (shl (ashr x, #sr), #sl), #m) LogicalSR = false; Match = match(In, m_And(m_Shl(m_AShr(m_Value(BF), m_ConstantInt(CSR)), m_ConstantInt(CSL)), m_ConstantInt(CM))); } if (!Match) { // (and (shl x, #sl), #m) LogicalSR = true; CSR = ConstantInt::get(Type::getInt32Ty(Ctx), 0); Match = match(In, m_And(m_Shl(m_Value(BF), m_ConstantInt(CSL)), m_ConstantInt(CM))); if (Match && NoSR0) return false; } if (!Match) { // (and (lshr x, #sr), #m) LogicalSR = true; CSL = ConstantInt::get(Type::getInt32Ty(Ctx), 0); Match = match(In, m_And(m_LShr(m_Value(BF), m_ConstantInt(CSR)), m_ConstantInt(CM))); } if (!Match) { // (and (ashr x, #sr), #m) LogicalSR = false; CSL = ConstantInt::get(Type::getInt32Ty(Ctx), 0); Match = match(In, m_And(m_AShr(m_Value(BF), m_ConstantInt(CSR)), m_ConstantInt(CM))); } if (!Match) { CM = nullptr; // (shl (lshr x, #sr), #sl) LogicalSR = true; Match = match(In, m_Shl(m_LShr(m_Value(BF), m_ConstantInt(CSR)), m_ConstantInt(CSL))); } if (!Match) { CM = nullptr; // (shl (ashr x, #sr), #sl) LogicalSR = false; Match = match(In, m_Shl(m_AShr(m_Value(BF), m_ConstantInt(CSR)), m_ConstantInt(CSL))); } if (!Match) return false; Type *Ty = BF->getType(); if (!Ty->isIntegerTy()) return false; unsigned BW = Ty->getPrimitiveSizeInBits(); if (BW != 32 && BW != 64) return false; uint32_t SR = CSR->getZExtValue(); uint32_t SL = CSL->getZExtValue(); if (!CM) { // If there was no and, and the shift left did not remove all potential // sign bits created by the shift right, then extractu cannot reproduce // this value. if (!LogicalSR && (SR > SL)) return false; APInt A = APInt(BW, ~0ULL).lshr(SR).shl(SL); CM = ConstantInt::get(Ctx, A); } // CM is the shifted-left mask. Shift it back right to remove the zero // bits on least-significant positions. APInt M = CM->getValue().lshr(SL); uint32_t T = M.countTrailingOnes(); // During the shifts some of the bits will be lost. Calculate how many // of the original value will remain after shift right and then left. uint32_t U = BW - std::max(SL, SR); // The width of the extracted field is the minimum of the original bits // that remain after the shifts and the number of contiguous 1s in the mask. uint32_t W = std::min(U, T); if (W == 0 || W == 1) return false; // Check if the extracted bits are contained within the mask that it is // and-ed with. The extract operation will copy these bits, and so the // mask cannot any holes in it that would clear any of the bits of the // extracted field. if (!LogicalSR) { // If the shift right was arithmetic, it could have included some 1 bits. // It is still ok to generate extract, but only if the mask eliminates // those bits (i.e. M does not have any bits set beyond U). APInt C = APInt::getHighBitsSet(BW, BW-U); if (M.intersects(C) || !M.isMask(W)) return false; } else { // Check if M starts with a contiguous sequence of W times 1 bits. Get // the low U bits of M (which eliminates the 0 bits shifted in on the // left), and check if the result is APInt's "mask": if (!M.getLoBits(U).isMask(W)) return false; } IRBuilder<> IRB(In); Intrinsic::ID IntId = (BW == 32) ? Intrinsic::hexagon_S2_extractu : Intrinsic::hexagon_S2_extractup; Module *Mod = BB->getParent()->getParent(); Function *ExtF = Intrinsic::getDeclaration(Mod, IntId); Value *NewIn = IRB.CreateCall(ExtF, {BF, IRB.getInt32(W), IRB.getInt32(SR)}); if (SL != 0) NewIn = IRB.CreateShl(NewIn, SL, CSL->getName()); In->replaceAllUsesWith(NewIn); return true; } bool HexagonGenExtract::visitBlock(BasicBlock *B) { bool Changed = false; // Depth-first, bottom-up traversal. for (auto *DTN : children<DomTreeNode*>(DT->getNode(B))) Changed |= visitBlock(DTN->getBlock()); // Allow limiting the number of generated extracts for debugging purposes. bool HasCutoff = ExtractCutoff.getPosition(); unsigned Cutoff = ExtractCutoff; BasicBlock::iterator I = std::prev(B->end()), NextI, Begin = B->begin(); while (true) { if (HasCutoff && (ExtractCount >= Cutoff)) return Changed; bool Last = (I == Begin); if (!Last) NextI = std::prev(I); Instruction *In = &*I; bool Done = convert(In); if (HasCutoff && Done) ExtractCount++; Changed |= Done; if (Last) break; I = NextI; } return Changed; } bool HexagonGenExtract::runOnFunction(Function &F) { if (skipFunction(F)) return false; DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree(); bool Changed; // Traverse the function bottom-up, to see super-expressions before their // sub-expressions. BasicBlock *Entry = GraphTraits<Function*>::getEntryNode(&F); Changed = visitBlock(Entry); return Changed; } FunctionPass *llvm::createHexagonGenExtract() { return new HexagonGenExtract(); }
Upload File
Create Folder