[llvm-branch-commits] [llvm] 05b1a15 - [IROutliner] Adapting to hoisted bitcasts in CodeExtractor
Author: Andrew Litteken Date: 2021-01-13T11:10:37-06:00 New Revision: 05b1a15f703c3e01f4123424700bc37188af8af1 URL: https://github.com/llvm/llvm-project/commit/05b1a15f703c3e01f4123424700bc37188af8af1 DIFF: https://github.com/llvm/llvm-project/commit/05b1a15f703c3e01f4123424700bc37188af8af1.diff LOG: [IROutliner] Adapting to hoisted bitcasts in CodeExtractor In commit 700d2417d8281ea56dfd7ac72d1a1473d03d2d59 the CodeExtractor was updated so that bitcasts that have lifetime markers that beginning outside of the region are deduplicated outside the region and are not used as an output. This caused a discrepancy in the IROutliner, where in these cases there were arguments added to the aggregate function that were not needed causing assertion errors. The IROutliner queries the CodeExtractor twice to determine the inputs and outputs, before and after `findAllocas` is called with the same ValueSet for the outputs causing the duplication. This has been fixed with a dummy ValueSet for the first call. However, the additional bitcasts prevent us from using the same similarity relationships that were previously defined by the IR Similarity Analysis Pass. In these cases, we check whether the initial version of the region being analyzed for outlining is still the same as it was previously. If it is not, i.e. because of the additional bitcast instructions from the CodeExtractor, we discard the region. Reviewers: yroux Differential Revision: https://reviews.llvm.org/D94303 Added: llvm/test/Transforms/IROutliner/outlining-bitcasts.ll Modified: llvm/lib/Transforms/IPO/IROutliner.cpp Removed: diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index 0e5e1dd0886e..f6fdd69d71c3 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -510,13 +510,16 @@ static void getCodeExtractorArguments( // outlined region. PremappedInputs are the arguments found by the // CodeExtractor, removing conditions such as sunken allocas, but that // may need to be remapped due to the extracted output values replacing - // the original values. - SetVector OverallInputs, PremappedInputs, SinkCands, HoistCands; + // the original values. We use DummyOutputs for this first run of finding + // inputs and outputs since the outputs could change during findAllocas, + // the correct set of extracted outputs will be in the final Outputs ValueSet. + SetVector OverallInputs, PremappedInputs, SinkCands, HoistCands, + DummyOutputs; // Use the code extractor to get the inputs and outputs, without sunken // allocas or removing llvm.assumes. CodeExtractor *CE = Region.CE; - CE->findInputsOutputs(OverallInputs, Outputs, SinkCands); + CE->findInputsOutputs(OverallInputs, DummyOutputs, SinkCands); assert(Region.StartBB && "Region must have a start BasicBlock!"); Function *OrigF = Region.StartBB->getParent(); CodeExtractorAnalysisCache CEAC(*OrigF); @@ -1263,6 +1266,16 @@ void IROutliner::pruneIncompatibleRegions( continue; bool BadInst = any_of(IRSC, [this](IRInstructionData &ID) { + // We check if there is a discrepancy between the InstructionDataList + // and the actual next instruction in the module. If there is, it means + // that an extra instruction was added, likely by the CodeExtractor. + + // Since we do not have any similarity data about this particular + // instruction, we cannot confidently outline it, and must discard this + // candidate. + if (std::next(ID.getIterator())->Inst != + ID.Inst->getNextNonDebugInstruction()) +return true; return !this->InstructionClassifier.visit(ID.Inst); }); diff --git a/llvm/test/Transforms/IROutliner/outlining-bitcasts.ll b/llvm/test/Transforms/IROutliner/outlining-bitcasts.ll new file mode 100644 index ..68b7eb74ec0c --- /dev/null +++ b/llvm/test/Transforms/IROutliner/outlining-bitcasts.ll @@ -0,0 +1,105 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s + +; This test ensures that an extra output is not added when there is a bitcast +; that is relocated to outside of the extraction due to a starting lifetime +; instruction outside of the extracted region. + +; Additionally, we check that the newly added bitcast instruction is excluded in +; further extractions. + +declare void @llvm.lifetime.start.p0i8(i64, i8* nocapture) +declare void @llvm.lifetime.end.p0i8(i64, i8* nocapture) + +define void @outline_bitcast_base() { +; CHECK-LABEL: @outline_bitcast_base( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT:[[B:%.*]] = alloca i32, align 4 +; CHECK-NEXT:[[C:%.*]] = alloca i32, align 4 +; CHECK-NEXT:[[D:%.*]] = alloca i32, align 4 +; CHECK
[llvm-branch-commits] [llvm] e6ae623 - [IROutliner] Adding support for consolidating functions with different output arguments.
Author: Andrew Litteken Date: 2020-12-28T16:17:07-06:00 New Revision: e6ae623314bab3ddd983ed941bf63a6d4c63a1f4 URL: https://github.com/llvm/llvm-project/commit/e6ae623314bab3ddd983ed941bf63a6d4c63a1f4 DIFF: https://github.com/llvm/llvm-project/commit/e6ae623314bab3ddd983ed941bf63a6d4c63a1f4.diff LOG: [IROutliner] Adding support for consolidating functions with different output arguments. Certain regions can have values introduced inside the region that are used outside of the region. These may not be the same for each similar region, so we must create one over arching set of arguments for the consolidated function. We do this by iterating over the outputs for each extracted function, and creating as many different arguments to encapsulate the different outputs sets. For each output set, we create a different block with the necessary stores from the value to the output register. There is then one switch statement, controlled by an argument to the function, to differentiate which block to use. Changed Tests for consistency: llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/illegal-assumes.ll llvm/test/Transforms/IROutliner/illegal-memcpy.ll llvm/test/Transforms/IROutliner/illegal-memmove.ll llvm/test/Transforms/IROutliner/illegal-vaarg.ll Tests to test new functionality: llvm/test/Transforms/IROutliner/outlining-different-output-blocks.ll llvm/test/Transforms/IROutliner/outlining-remapped-outputs.ll llvm/test/Transforms/IROutliner/outlining-same-output-blocks.ll Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87296 Added: llvm/test/Transforms/IROutliner/outlining-different-output-blocks.ll llvm/test/Transforms/IROutliner/outlining-remapped-outputs.ll llvm/test/Transforms/IROutliner/outlining-same-output-blocks.ll Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/illegal-assumes.ll llvm/test/Transforms/IROutliner/illegal-memcpy.ll llvm/test/Transforms/IROutliner/illegal-memmove.ll llvm/test/Transforms/IROutliner/illegal-vaarg.ll Removed: diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index 87f276d82df7..2048d6d6d1a1 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -73,6 +73,10 @@ struct OutlinableRegion { /// The number of extracted inputs from the CodeExtractor. unsigned NumExtractedInputs; + /// The corresponding BasicBlock with the appropriate stores for this + /// OutlinableRegion in the overall function. + unsigned OutputBlockNum; + /// Mapping the extracted argument number to the argument number in the /// overall function. Since there will be inputs, such as elevated constants /// that are not the same in each region in a SimilarityGroup, or values that @@ -87,6 +91,11 @@ struct OutlinableRegion { /// since the CodeExtractor does not recognize constants. DenseMap AggArgToConstant; + /// The global value numbers that are used as outputs for this section. Once + /// extracted, each output will be stored to an output register. This + /// documents the global value numbers that are used in this pattern. + SmallVector GVNStores; + /// Used to create an outlined function. CodeExtractor *CE = nullptr; @@ -192,6 +201,15 @@ class IROutliner { void findAddInputsOutputs(Module &M, OutlinableRegion &Region, DenseSet &NotSame); + /// Update the output mapping based on the load instruction, and the outputs + /// of the extracted function. + /// + /// \param Region - The region extracted + /// \param Outputs - The outputs from the extracted function. + /// \param LI - The load instruction used to update the mapping. + void updateOutputMapping(OutlinableRegion &Region, + ArrayRef Outputs, LoadInst *LI); + /// Extract \p Region into its own function. /// /// \param [in] Region - The region to be extracted into its own function. @@ -218,6 +236,11 @@ class IROutliner { /// TargetTransformInfo lambda for target specific information. function_ref getTTI; + /// A mapping from newly created reloaded output values to the original value. + /// If an value is replace by an output from an outlined region, this maps + /// that Value, back to its original Value. + DenseMap OutputMappings; + /// IRSimilarityIdentifier lambda to retrieve IRSimilarityIdentifier. function_ref getIRSI; diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index 12a30744a652..ec6bfaef26ec 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -50,6 +50,9 @@ struct OutlinableGroup {
[llvm-branch-commits] [llvm] 1e23802 - [IROutliner] Merging identical output blocks for extracted functions.
Author: Andrew Litteken Date: 2020-12-28T21:01:48-06:00 New Revision: 1e23802507d18ef8cb5a063325ff442ac7f527be URL: https://github.com/llvm/llvm-project/commit/1e23802507d18ef8cb5a063325ff442ac7f527be DIFF: https://github.com/llvm/llvm-project/commit/1e23802507d18ef8cb5a063325ff442ac7f527be.diff LOG: [IROutliner] Merging identical output blocks for extracted functions. Many of the sets of output stores will be the same. When a block is created, we check if there is an output block with the same set of store instructions. If there is, we map the output block of the region back to the block, so that the extra argument controlling the switch statement can be set to the appropriate block value. Tests: - llvm/test/Transforms/IROutliner/outlining-same-output-blocks.ll Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87298 Added: Modified: llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/illegal-assumes.ll llvm/test/Transforms/IROutliner/illegal-memcpy.ll llvm/test/Transforms/IROutliner/illegal-memmove.ll llvm/test/Transforms/IROutliner/illegal-vaarg.ll llvm/test/Transforms/IROutliner/outlining-remapped-outputs.ll llvm/test/Transforms/IROutliner/outlining-same-output-blocks.ll Removed: diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index ec6bfaef26ec..4c0e09911ab9 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -53,6 +53,11 @@ struct OutlinableGroup { /// The return block for the overall function. BasicBlock *EndBB = nullptr; + /// A set containing the diff erent GVN store sets needed. Each array contains + /// a sorted list of the diff erent values that need to be stored into output + /// registers. + DenseSet> OutputGVNCombinations; + /// Flag for whether the \ref ArgumentTypes have been defined after the /// extraction of the first region. bool InputTypesSet = false; @@ -67,6 +72,13 @@ struct OutlinableGroup { /// \param [in,out] NotSame contains the global value numbers where the /// constant is not always the same, and must be passed in as an argument. void findSameConstants(DenseSet &NotSame); + + /// For the regions, look at each set of GVN stores needed and account for + /// each combination. Add an argument to the argument types if there is + /// more than one combination. + /// + /// \param [in] M - The module we are outlining from. + void collectGVNStoreSets(Module &M); }; /// Move the contents of \p SourceBB to before the last instruction of \p @@ -266,6 +278,17 @@ void OutlinableGroup::findSameConstants(DenseSet &NotSame) { collectRegionsConstants(*Region, GVNToConstant, NotSame); } +void OutlinableGroup::collectGVNStoreSets(Module &M) { + for (OutlinableRegion *OS : Regions) +OutputGVNCombinations.insert(OS->GVNStores); + + // We are adding an extracted argument to decide between which output path + // to use in the basic block. It is used in a switch statement and only + // needs to be an integer. + if (OutputGVNCombinations.size() > 1) +ArgumentTypes.push_back(Type::getInt32Ty(M.getContext())); +} + Function *IROutliner::createFunction(Module &M, OutlinableGroup &Group, unsigned FunctionNameSuffix) { assert(!Group.OutlinedFunction && "Function is already defined!"); @@ -655,7 +678,7 @@ CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) { for (unsigned AggArgIdx = 0; AggArgIdx < AggFunc->arg_size(); AggArgIdx++) { if (AggArgIdx == AggFunc->arg_size() - 1 && -Group.ArgumentTypes.size() > Group.NumAggregateInputs) { +Group.OutputGVNCombinations.size() > 1) { // If we are on the last argument, and we need to diff erentiate between // output blocks, add an integer to the argument list to determine // what block to take @@ -703,9 +726,9 @@ CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) { Call); // It is possible that the call to the outlined function is either the first - // instruction in the new block, the last instruction, or both. If either of - // these is the case, we need to make sure that we replace the instruction in - // the IRInstructionData struct with the new call. + // instruction is in the new block, the last instruction, or both. If either + // of these is the case, we need to make sure that we replace the instruction + // in the IRInstructionData struct with the new call. CallInst *OldCall = Region.Call; if (Region.NewFront->Inst == OldCall) Region.NewFront->Inst = Call; @@ -831,8 +854,51 @@ collectRelevantInstructions(Function &F, return RelevantInstructions; } +/// It is possible that there is a basic
[llvm-branch-commits] [llvm] 6df161a - [IROutliner] Adding a cost model, and debug option to turn the model off.
Author: Andrew Litteken Date: 2020-12-29T12:43:41-06:00 New Revision: 6df161a2fbf62bd4ab7297fe1fb234cdc972a48b URL: https://github.com/llvm/llvm-project/commit/6df161a2fbf62bd4ab7297fe1fb234cdc972a48b DIFF: https://github.com/llvm/llvm-project/commit/6df161a2fbf62bd4ab7297fe1fb234cdc972a48b.diff LOG: [IROutliner] Adding a cost model, and debug option to turn the model off. This adds a cost model that takes into account the total number of machine instructions to be removed from each region, the number of instructions added by adding a new function with a set of instructions, and the instructions added by handling arguments. Tests not adding flags: llvm/test/Transforms/IROutliner/outlining-cost-model.ll Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87299 Added: llvm/test/Transforms/IROutliner/outlining-cost-model.ll llvm/test/Transforms/IROutliner/outlining-debug-statements.ll Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/illegal-allocas.ll llvm/test/Transforms/IROutliner/illegal-assumes.ll llvm/test/Transforms/IROutliner/illegal-branches.ll llvm/test/Transforms/IROutliner/illegal-callbr.ll llvm/test/Transforms/IROutliner/illegal-calls.ll llvm/test/Transforms/IROutliner/illegal-catchpad.ll llvm/test/Transforms/IROutliner/illegal-cleanup.ll llvm/test/Transforms/IROutliner/illegal-frozen.ll llvm/test/Transforms/IROutliner/illegal-gep.ll llvm/test/Transforms/IROutliner/illegal-invoke.ll llvm/test/Transforms/IROutliner/illegal-landingpad.ll llvm/test/Transforms/IROutliner/illegal-memcpy.ll llvm/test/Transforms/IROutliner/illegal-memmove.ll llvm/test/Transforms/IROutliner/illegal-memset.ll llvm/test/Transforms/IROutliner/illegal-phi-nodes.ll llvm/test/Transforms/IROutliner/illegal-vaarg.ll llvm/test/Transforms/IROutliner/legal-debug.ll llvm/test/Transforms/IROutliner/outlining-address-taken.ll llvm/test/Transforms/IROutliner/outlining-commutative-fp.ll llvm/test/Transforms/IROutliner/outlining-commutative.ll llvm/test/Transforms/IROutliner/outlining-constants-vs-registers.ll llvm/test/Transforms/IROutliner/outlining-different-constants.ll llvm/test/Transforms/IROutliner/outlining-different-globals.ll llvm/test/Transforms/IROutliner/outlining-different-output-blocks.ll llvm/test/Transforms/IROutliner/outlining-different-structure.ll llvm/test/Transforms/IROutliner/outlining-remapped-outputs.ll llvm/test/Transforms/IROutliner/outlining-same-constants.ll llvm/test/Transforms/IROutliner/outlining-same-globals.ll llvm/test/Transforms/IROutliner/outlining-same-output-blocks.ll Removed: diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index 2048d6d6d1a1..0cba35f637c6 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -145,6 +145,12 @@ struct OutlinableRegion { /// function has been extracted, the start and end of the BasicBlock /// containing the called function. void reattachCandidate(); + + /// Get the size of the code removed from the region. + /// + /// \param [in] TTI - The TargetTransformInfo for the parent function. + /// \returns the code size of the region + unsigned getBenefit(TargetTransformInfo &TTI); }; /// This class is a pass that identifies similarity in a Module, extracts @@ -201,6 +207,28 @@ class IROutliner { void findAddInputsOutputs(Module &M, OutlinableRegion &Region, DenseSet &NotSame); + /// Find the number of instructions that will be removed by extracting the + /// OutlinableRegions in \p CurrentGroup. + /// + /// \param [in] CurrentGroup - The collection of OutlinableRegions to be + /// analyzed. + /// \returns the number of outlined instructions across all regions. + unsigned findBenefitFromAllRegions(OutlinableGroup &CurrentGroup); + + /// Find the number of instructions that will be added by reloading arguments. + /// + /// \param [in] CurrentGroup - The collection of OutlinableRegions to be + /// analyzed. + /// \returns the number of added reload instructions across all regions. + unsigned findCostOutputReloads(OutlinableGroup &CurrentGroup); + + /// Find the cost and the benefit of \p CurrentGroup and save it back to + /// \p CurrentGroup. + /// + /// \param [in] M - The module being analyzed + /// \param [in,out] CurrentGroup - The overall outlined section + void findCostBenefit(Module &M, OutlinableGroup &CurrentGroup); + /// Update the output mapping based on the load instruction, and the outputs /// of the extracted function. /// @@ -229,6 +257,11 @@ class IROutliner {
[llvm-branch-commits] [llvm] df4a931 - [IROutliner] Adding OptRemarks to the IROutliner Pass
Author: Andrew Litteken Date: 2020-12-29T15:52:08-06:00 New Revision: df4a931c63b60db4589e348e8f8ab9a49e093aa7 URL: https://github.com/llvm/llvm-project/commit/df4a931c63b60db4589e348e8f8ab9a49e093aa7 DIFF: https://github.com/llvm/llvm-project/commit/df4a931c63b60db4589e348e8f8ab9a49e093aa7.diff LOG: [IROutliner] Adding OptRemarks to the IROutliner Pass This prints OptRemarks at each location where a decision is made to not outline, or to outline a specific section for the IROutliner pass. Test: llvm/test/Transforms/IROutliner/opt-remarks.ll Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87300 Added: llvm/test/Transforms/IROutliner/opt-remarks.ll Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp Removed: diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index 0cba35f637c6..6291af741184 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -162,8 +162,9 @@ struct OutlinableRegion { class IROutliner { public: IROutliner(function_ref GTTI, - function_ref GIRSI) - : getTTI(GTTI), getIRSI(GIRSI) {} + function_ref GIRSI, + function_ref GORE) + : getTTI(GTTI), getIRSI(GIRSI), getORE(GORE) {} bool run(Module &M); private: @@ -277,6 +278,9 @@ class IROutliner { /// IRSimilarityIdentifier lambda to retrieve IRSimilarityIdentifier. function_ref getIRSI; + /// The optimization remark emitter for the pass. + function_ref getORE; + /// The memory allocator used to allocate the CodeExtractors. SpecificBumpPtrAllocator ExtractorAllocator; diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index da90f1a12871..d972908f507d 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -13,6 +13,7 @@ #include "llvm/Transforms/IPO/IROutliner.h" #include "llvm/Analysis/IRSimilarityIdentifier.h" +#include "llvm/Analysis/OptimizationRemarkEmitter.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/IR/Attributes.h" #include "llvm/IR/PassManager.h" @@ -216,6 +217,7 @@ constantMatches(Value *V, unsigned GVN, DenseMap::iterator GVNToConstantIt; bool Inserted; + // If we have a constant, try to make a new entry in the GVNToConstant. std::tie(GVNToConstantIt, Inserted) = GVNToConstant.insert(std::make_pair(GVN, CST)); @@ -1549,6 +1551,29 @@ unsigned IROutliner::doOutline(Module &M) { if (CurrentGroup.Cost >= CurrentGroup.Benefit && CostModel) { for (OutlinableRegion *OS : CurrentGroup.Regions) OS->reattachCandidate(); + OptimizationRemarkEmitter &ORE = getORE( + *CurrentGroup.Regions[0]->Candidate->getFunction()); + ORE.emit([&]() { +IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate; +OptimizationRemarkMissed R(DEBUG_TYPE, "WouldNotDecreaseSize", + C->frontInstruction()); +R << "did not outline " + << ore::NV(std::to_string(CurrentGroup.Regions.size())) + << " regions due to estimated increase of " + << ore::NV("InstructionIncrease", + std::to_string(static_cast(CurrentGroup.Cost - + CurrentGroup.Benefit))) + << " instructions at locations "; +interleave( +CurrentGroup.Regions.begin(), CurrentGroup.Regions.end(), +[&R](OutlinableRegion *Region) { + R << ore::NV( + "DebugLoc", + Region->Candidate->frontInstruction()->getDebugLoc()); +}, +[&R]() { R << " "; }); +return R; + }); continue; } @@ -1569,11 +1594,35 @@ unsigned IROutliner::doOutline(Module &M) { } } +LLVM_DEBUG(dbgs() << "Outlined " << OutlinedRegions.size() + << " with benefit " << CurrentGroup.Benefit + << " and cost " << CurrentGroup.Cost << "\n"); + CurrentGroup.Regions = std::move(OutlinedRegions); if (CurrentGroup.Regions.empty()) continue; +OptimizationRemarkEmitter &ORE = +getORE(*CurrentGroup.Regions[0]->Call->getFunction()); +ORE.emit([&]() { + IRSimilarityCandidate *C = CurrentGroup.Regions[0]->Candidate; + OptimizationRemark R(DEBUG_TYPE, "Outlined", C->front()->Inst); + R << "outlined " << ore::NV(std::to_string(CurrentGroup.Regions.size())) +<< " regions with decrease of " +<< ore::NV("Benefit", std::to_string(static_cast( + CurrentGroup.Benefit - CurrentGroup.Cost))) +<< " instructions at locations "; + interleave( + CurrentGroup.Regions.beg
[llvm-branch-commits] [llvm] 71867ed - [IROutliner] Adding support for swift errors
Author: Andrew Litteken Date: 2020-12-30T01:14:55-06:00 New Revision: 71867ed5e6606a93f0c1413f205afe3bb16317fe URL: https://github.com/llvm/llvm-project/commit/71867ed5e6606a93f0c1413f205afe3bb16317fe DIFF: https://github.com/llvm/llvm-project/commit/71867ed5e6606a93f0c1413f205afe3bb16317fe.diff LOG: [IROutliner] Adding support for swift errors Added: llvm/test/Transforms/IROutliner/outlining-swift-error.ll Modified: llvm/lib/Transforms/IPO/IROutliner.cpp Removed: diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index d972908f507d..5289826f4a9a 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -81,6 +81,10 @@ struct OutlinableGroup { /// Regions. unsigned Cost = 0; + /// The argument that needs to be marked with the swifterr attribute. If not + /// needed, there is no value. + Optional SwiftErrorArgument; + /// For the \ref Regions, we look at every Value. If it is a constant, /// we check whether it is the same in Region. /// @@ -352,6 +356,11 @@ Function *IROutliner::createFunction(Module &M, OutlinableGroup &Group, Group.OutlinedFunctionType, GlobalValue::InternalLinkage, "outlined_ir_func_" + std::to_string(FunctionNameSuffix), M); + // Transfer the swifterr attribute to the correct function parameter. + if (Group.SwiftErrorArgument.hasValue()) +Group.OutlinedFunction->addParamAttr(Group.SwiftErrorArgument.getValue(), + Attribute::SwiftError); + Group.OutlinedFunction->addFnAttr(Attribute::OptimizeForSize); Group.OutlinedFunction->addFnAttr(Attribute::MinSize); @@ -570,8 +579,17 @@ findExtractedInputToOverallInputMapping(OutlinableRegion &Region, assert(InputOpt.hasValue() && "Global value number not found?"); Value *Input = InputOpt.getValue(); -if (!Group.InputTypesSet) +if (!Group.InputTypesSet) { Group.ArgumentTypes.push_back(Input->getType()); + // If the input value has a swifterr attribute, make sure to mark the + // argument in the overall function. + if (Input->isSwiftError()) { +assert( +!Group.SwiftErrorArgument.hasValue() && +"Argument already marked with swifterr for this OutlinableGroup!"); +Group.SwiftErrorArgument = TypeIndex; + } +} // Check if we have a constant. If we do add it to the overall argument // number to Constant map for the region, and continue to the next input. @@ -792,6 +810,12 @@ CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) { OldCall->eraseFromParent(); Region.Call = Call; + // Make sure that the argument in the new function has the SwiftError + // argument. + if (Group.SwiftErrorArgument.hasValue()) +Call->addParamAttr(Group.SwiftErrorArgument.getValue(), + Attribute::SwiftError); + return Call; } diff --git a/llvm/test/Transforms/IROutliner/outlining-swift-error.ll b/llvm/test/Transforms/IROutliner/outlining-swift-error.ll new file mode 100644 index ..a6012cdeb329 --- /dev/null +++ b/llvm/test/Transforms/IROutliner/outlining-swift-error.ll @@ -0,0 +1,47 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s + +%swift.error = type opaque + +define void @outlining_swifterror1(%swift.error** swifterror %err) { +; CHECK-LABEL: @outlining_swifterror1( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[X:%.*]] = alloca i64, align 8 +; CHECK-NEXT:call void @outlined_ir_func_0(i64 5, i64* [[X]], %swift.error** swifterror [[ERR:%.*]]) +; CHECK-NEXT:ret void +; +entry: + %x = alloca i64 + %0 = mul i64 5, 5 + %1 = add i64 %0, %0 + store i64 %1, i64* %x + %casted = bitcast i64* %x to %swift.error* + store %swift.error* %casted, %swift.error** %err + ret void +} + +define void @outlining_swifterror2(%swift.error** swifterror %err) { +; CHECK-LABEL: @outlining_swifterror2( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[X:%.*]] = alloca i64, align 8 +; CHECK-NEXT:call void @outlined_ir_func_0(i64 3, i64* [[X]], %swift.error** swifterror [[ERR:%.*]]) +; CHECK-NEXT:ret void +; +entry: + %x = alloca i64 + %0 = mul i64 3, 3 + %1 = add i64 %0, %0 + store i64 %1, i64* %x + %casted = bitcast i64* %x to %swift.error* + store %swift.error* %casted, %swift.error** %err + ret void +} + +; CHECK: define internal void @outlined_ir_func_0(i64 [[ARG0:%.*]], i64* [[ARG1:%.*]], %swift.error** swifterror [[ARG2:%.*]]) +; CHECK: entry_to_outline: +; CHECK-NEXT: [[TMP0:%.*]] = mul i64 [[ARG0]], [[ARG0]] +; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], [[TMP0]] +; CHECK-NEXT: store i64 [[TMP1]], i64* [[ARG1]], align 4 +; CHECK-NEXT: %casted = bitcast i64* [[ARG1]] to %swift.error* +; CHECK-NEXT: store %swi
[llvm-branch-commits] [llvm] eeb99c2 - Revert "[IROutliner] Adding support for swift errors"
Author: Andrew Litteken Date: 2020-12-30T01:17:27-06:00 New Revision: eeb99c2ac2672c8a61085e94f66b1b31c524cd87 URL: https://github.com/llvm/llvm-project/commit/eeb99c2ac2672c8a61085e94f66b1b31c524cd87 DIFF: https://github.com/llvm/llvm-project/commit/eeb99c2ac2672c8a61085e94f66b1b31c524cd87.diff LOG: Revert "[IROutliner] Adding support for swift errors" This reverts commit 71867ed5e6606a93f0c1413f205afe3bb16317fe. Reverting for lack of commit messages. Added: Modified: llvm/lib/Transforms/IPO/IROutliner.cpp Removed: llvm/test/Transforms/IROutliner/outlining-swift-error.ll diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index 5289826f4a9a..d972908f507d 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -81,10 +81,6 @@ struct OutlinableGroup { /// Regions. unsigned Cost = 0; - /// The argument that needs to be marked with the swifterr attribute. If not - /// needed, there is no value. - Optional SwiftErrorArgument; - /// For the \ref Regions, we look at every Value. If it is a constant, /// we check whether it is the same in Region. /// @@ -356,11 +352,6 @@ Function *IROutliner::createFunction(Module &M, OutlinableGroup &Group, Group.OutlinedFunctionType, GlobalValue::InternalLinkage, "outlined_ir_func_" + std::to_string(FunctionNameSuffix), M); - // Transfer the swifterr attribute to the correct function parameter. - if (Group.SwiftErrorArgument.hasValue()) -Group.OutlinedFunction->addParamAttr(Group.SwiftErrorArgument.getValue(), - Attribute::SwiftError); - Group.OutlinedFunction->addFnAttr(Attribute::OptimizeForSize); Group.OutlinedFunction->addFnAttr(Attribute::MinSize); @@ -579,17 +570,8 @@ findExtractedInputToOverallInputMapping(OutlinableRegion &Region, assert(InputOpt.hasValue() && "Global value number not found?"); Value *Input = InputOpt.getValue(); -if (!Group.InputTypesSet) { +if (!Group.InputTypesSet) Group.ArgumentTypes.push_back(Input->getType()); - // If the input value has a swifterr attribute, make sure to mark the - // argument in the overall function. - if (Input->isSwiftError()) { -assert( -!Group.SwiftErrorArgument.hasValue() && -"Argument already marked with swifterr for this OutlinableGroup!"); -Group.SwiftErrorArgument = TypeIndex; - } -} // Check if we have a constant. If we do add it to the overall argument // number to Constant map for the region, and continue to the next input. @@ -810,12 +792,6 @@ CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) { OldCall->eraseFromParent(); Region.Call = Call; - // Make sure that the argument in the new function has the SwiftError - // argument. - if (Group.SwiftErrorArgument.hasValue()) -Call->addParamAttr(Group.SwiftErrorArgument.getValue(), - Attribute::SwiftError); - return Call; } diff --git a/llvm/test/Transforms/IROutliner/outlining-swift-error.ll b/llvm/test/Transforms/IROutliner/outlining-swift-error.ll deleted file mode 100644 index a6012cdeb329.. --- a/llvm/test/Transforms/IROutliner/outlining-swift-error.ll +++ /dev/null @@ -1,47 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s - -%swift.error = type opaque - -define void @outlining_swifterror1(%swift.error** swifterror %err) { -; CHECK-LABEL: @outlining_swifterror1( -; CHECK-NEXT: entry: -; CHECK-NEXT:[[X:%.*]] = alloca i64, align 8 -; CHECK-NEXT:call void @outlined_ir_func_0(i64 5, i64* [[X]], %swift.error** swifterror [[ERR:%.*]]) -; CHECK-NEXT:ret void -; -entry: - %x = alloca i64 - %0 = mul i64 5, 5 - %1 = add i64 %0, %0 - store i64 %1, i64* %x - %casted = bitcast i64* %x to %swift.error* - store %swift.error* %casted, %swift.error** %err - ret void -} - -define void @outlining_swifterror2(%swift.error** swifterror %err) { -; CHECK-LABEL: @outlining_swifterror2( -; CHECK-NEXT: entry: -; CHECK-NEXT:[[X:%.*]] = alloca i64, align 8 -; CHECK-NEXT:call void @outlined_ir_func_0(i64 3, i64* [[X]], %swift.error** swifterror [[ERR:%.*]]) -; CHECK-NEXT:ret void -; -entry: - %x = alloca i64 - %0 = mul i64 3, 3 - %1 = add i64 %0, %0 - store i64 %1, i64* %x - %casted = bitcast i64* %x to %swift.error* - store %swift.error* %casted, %swift.error** %err - ret void -} - -; CHECK: define internal void @outlined_ir_func_0(i64 [[ARG0:%.*]], i64* [[ARG1:%.*]], %swift.error** swifterror [[ARG2:%.*]]) -; CHECK: entry_to_outline: -; CHECK-NEXT: [[TMP0:%.*]] = mul i64 [[ARG0]], [[ARG0]] -; CHECK-NEXT: [[TMP1:%.*]] = add i64 [[TMP0]], [[TMP0]] -; CHECK-NEXT: store i64 [[TMP1]]
[llvm-branch-commits] [llvm] 30feb93 - [IROutliner] Adding support for swift errors in the IROutliner
Author: Andrew Litteken Date: 2020-12-30T01:17:27-06:00 New Revision: 30feb93036ebb8ffc5233a9ab3960836c2407d95 URL: https://github.com/llvm/llvm-project/commit/30feb93036ebb8ffc5233a9ab3960836c2407d95 DIFF: https://github.com/llvm/llvm-project/commit/30feb93036ebb8ffc5233a9ab3960836c2407d95.diff LOG: [IROutliner] Adding support for swift errors in the IROutliner Since some values can be swift errors, we need to make sure that we correctly propagate the parameter attributes. Tests found at: llvm/test/Transforms/IROutliner/outlining-swift-error.ll Reviewers: jroelofs, paquette Recommit of: 71867ed5e6606a93f0c1413f205afe3bb16317fe Differential Revision: https://reviews.llvm.org/D87742 Added: llvm/test/Transforms/IROutliner/outlining-swift-error.ll Modified: llvm/lib/Transforms/IPO/IROutliner.cpp Removed: diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index d972908f507d..5289826f4a9a 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -81,6 +81,10 @@ struct OutlinableGroup { /// Regions. unsigned Cost = 0; + /// The argument that needs to be marked with the swifterr attribute. If not + /// needed, there is no value. + Optional SwiftErrorArgument; + /// For the \ref Regions, we look at every Value. If it is a constant, /// we check whether it is the same in Region. /// @@ -352,6 +356,11 @@ Function *IROutliner::createFunction(Module &M, OutlinableGroup &Group, Group.OutlinedFunctionType, GlobalValue::InternalLinkage, "outlined_ir_func_" + std::to_string(FunctionNameSuffix), M); + // Transfer the swifterr attribute to the correct function parameter. + if (Group.SwiftErrorArgument.hasValue()) +Group.OutlinedFunction->addParamAttr(Group.SwiftErrorArgument.getValue(), + Attribute::SwiftError); + Group.OutlinedFunction->addFnAttr(Attribute::OptimizeForSize); Group.OutlinedFunction->addFnAttr(Attribute::MinSize); @@ -570,8 +579,17 @@ findExtractedInputToOverallInputMapping(OutlinableRegion &Region, assert(InputOpt.hasValue() && "Global value number not found?"); Value *Input = InputOpt.getValue(); -if (!Group.InputTypesSet) +if (!Group.InputTypesSet) { Group.ArgumentTypes.push_back(Input->getType()); + // If the input value has a swifterr attribute, make sure to mark the + // argument in the overall function. + if (Input->isSwiftError()) { +assert( +!Group.SwiftErrorArgument.hasValue() && +"Argument already marked with swifterr for this OutlinableGroup!"); +Group.SwiftErrorArgument = TypeIndex; + } +} // Check if we have a constant. If we do add it to the overall argument // number to Constant map for the region, and continue to the next input. @@ -792,6 +810,12 @@ CallInst *replaceCalledFunction(Module &M, OutlinableRegion &Region) { OldCall->eraseFromParent(); Region.Call = Call; + // Make sure that the argument in the new function has the SwiftError + // argument. + if (Group.SwiftErrorArgument.hasValue()) +Call->addParamAttr(Group.SwiftErrorArgument.getValue(), + Attribute::SwiftError); + return Call; } diff --git a/llvm/test/Transforms/IROutliner/outlining-swift-error.ll b/llvm/test/Transforms/IROutliner/outlining-swift-error.ll new file mode 100644 index ..a6012cdeb329 --- /dev/null +++ b/llvm/test/Transforms/IROutliner/outlining-swift-error.ll @@ -0,0 +1,47 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s + +%swift.error = type opaque + +define void @outlining_swifterror1(%swift.error** swifterror %err) { +; CHECK-LABEL: @outlining_swifterror1( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[X:%.*]] = alloca i64, align 8 +; CHECK-NEXT:call void @outlined_ir_func_0(i64 5, i64* [[X]], %swift.error** swifterror [[ERR:%.*]]) +; CHECK-NEXT:ret void +; +entry: + %x = alloca i64 + %0 = mul i64 5, 5 + %1 = add i64 %0, %0 + store i64 %1, i64* %x + %casted = bitcast i64* %x to %swift.error* + store %swift.error* %casted, %swift.error** %err + ret void +} + +define void @outlining_swifterror2(%swift.error** swifterror %err) { +; CHECK-LABEL: @outlining_swifterror2( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[X:%.*]] = alloca i64, align 8 +; CHECK-NEXT:call void @outlined_ir_func_0(i64 3, i64* [[X]], %swift.error** swifterror [[ERR:%.*]]) +; CHECK-NEXT:ret void +; +entry: + %x = alloca i64 + %0 = mul i64 3, 3 + %1 = add i64 %0, %0 + store i64 %1, i64* %x + %casted = bitcast i64* %x to %swift.error* + store %swift.error* %casted, %swift.error** %err + ret void +} + +; CHECK: define internal void @outlined_ir_func_0(i64 [[ARG0:%.*]], i64*
[llvm-branch-commits] [llvm] fe43110 - [IROutliner] Adding option to enable outlining from linkonceodr functions
Author: Andrew Litteken Date: 2020-12-30T12:08:04-06:00 New Revision: fe431103b633278da9ece1e03d6b441c1d44d977 URL: https://github.com/llvm/llvm-project/commit/fe431103b633278da9ece1e03d6b441c1d44d977 DIFF: https://github.com/llvm/llvm-project/commit/fe431103b633278da9ece1e03d6b441c1d44d977.diff LOG: [IROutliner] Adding option to enable outlining from linkonceodr functions There are functions that the linker is able to automatically deduplicate, we do not outline from these functions by default. This allows for outlining from those functions. Tests: llvm/test/Transforms/IROutliner/outlining-odr.ll Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87309 Added: llvm/test/Transforms/IROutliner/outlining-odr.ll Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp Removed: diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index 6291af741184..947a70866b04 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -258,6 +258,10 @@ class IROutliner { std::vector &FuncsToRemove, unsigned &OutlinedFunctionNum); + /// If true, enables us to outline from functions that have LinkOnceFromODR + /// linkages. + bool OutlineFromLinkODRs = false; + /// If false, we do not worry if the cost is greater than the benefit. This /// is for debugging and testing, so that we can test small cases to ensure /// that the outlining is being done correctly. diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index 5289826f4a9a..908ba0c70e70 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -30,6 +30,16 @@ using namespace llvm; using namespace IRSimilarity; +// Set to true if the user wants the ir outliner to run on linkonceodr linkage +// functions. This is false by default because the linker can dedupe linkonceodr +// functions. Since the outliner is confined to a single module (modulo LTO), +// this is off by default. It should, however, be the default behavior in +// LTO. +static cl::opt EnableLinkOnceODRIROutlining( +"enable-linkonceodr-ir-outlining", cl::Hidden, +cl::desc("Enable the IR outliner on linkonceodr functions"), +cl::init(false)); + // This is a debug option to test small pieces of code to ensure that outlining // works correctly. static cl::opt NoCostModel( @@ -1243,6 +1253,10 @@ void IROutliner::pruneIncompatibleRegions( if (IRSC.getStartBB()->hasAddressTaken()) continue; +if (IRSC.front()->Inst->getFunction()->hasLinkOnceODRLinkage() && +!OutlineFromLinkODRs) + continue; + // Greedily prune out any regions that will overlap with already chosen // regions. if (CurrentEndIdx != 0 && StartIdx <= CurrentEndIdx) @@ -1659,6 +1673,7 @@ unsigned IROutliner::doOutline(Module &M) { bool IROutliner::run(Module &M) { CostModel = !NoCostModel; + OutlineFromLinkODRs = EnableLinkOnceODRIROutlining; return doOutline(M) > 0; } diff --git a/llvm/test/Transforms/IROutliner/outlining-odr.ll b/llvm/test/Transforms/IROutliner/outlining-odr.ll new file mode 100644 index ..074de37c40bf --- /dev/null +++ b/llvm/test/Transforms/IROutliner/outlining-odr.ll @@ -0,0 +1,70 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -verify -iroutliner --ir-outlining-no-cost < %s | FileCheck %s +; RUN: opt -S -verify -iroutliner -enable-linkonceodr-ir-outlining --ir-outlining-no-cost < %s | FileCheck -check-prefix=ODR %s + +; This test looks at the constants in the regions, and if it they are the +; same it outlines them as constants rather than elevating them to arguments. + +define linkonce_odr void @outline_odr1() { +; ODR-LABEL: @outline_odr1( +; ODR-NEXT: entry: +; ODR-NEXT:[[A:%.*]] = alloca i32, align 4 +; ODR-NEXT:[[B:%.*]] = alloca i32, align 4 +; ODR-NEXT:[[C:%.*]] = alloca i32, align 4 +; ODR-NEXT:call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]]) +; ODR-NEXT:ret void +; CHECK-LABEL: @outline_odr1( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT:[[B:%.*]] = alloca i32, align 4 +; CHECK-NEXT:[[C:%.*]] = alloca i32, align 4 +; CHECK-NEXT:store i32 2, i32* [[A]], align 4 +; CHECK-NEXT:store i32 3, i32* [[B]], align 4 +; CHECK-NEXT:store i32 4, i32* [[C]], align 4 +; CHECK-NEXT:[[AL:%.*]] = load i32, i32* [[A]], align 4 +; CHECK-NEXT:[[BL:%.*]] = load i32, i32* [[B]], align 4 +; CHECK-NEXT:[[CL:%.*]] = load i32, i32* [[C]], align 4 +entry: + %a = alloca i32, align 4 + %b = alloca i32, align 4 + %c = alloca i32, align 4 + store i32
[llvm-branch-commits] [llvm] 1a9eb19 - [IROutliner] Adding consistent function attribute merging
Author: Andrew Litteken Date: 2020-12-31T12:30:23-06:00 New Revision: 1a9eb19af9ba1c6fcd63f84f4053c77881e6ae1c URL: https://github.com/llvm/llvm-project/commit/1a9eb19af9ba1c6fcd63f84f4053c77881e6ae1c DIFF: https://github.com/llvm/llvm-project/commit/1a9eb19af9ba1c6fcd63f84f4053c77881e6ae1c.diff LOG: [IROutliner] Adding consistent function attribute merging When combining extracted functions, they may have different function attributes. We want to make sure that we do not make any assumptions, or lose any information. This attempts to make sure that we consolidate function attributes to their most general case. Tests: llvm/test/Transforms/IROutliner/outlining-compatible-and-attribute-transfer.ll llvm/test/Transforms/IROutliner/outlining-compatible-or-attribute-transfer.ll Reviewers: jdoefert, paquette Differential Revision: https://reviews.llvm.org/D87301 Added: llvm/test/Transforms/IROutliner/outlining-compatible-and-attribute-transfer.ll llvm/test/Transforms/IROutliner/outlining-compatible-or-attribute-transfer.ll Modified: llvm/include/llvm/IR/Attributes.h llvm/lib/IR/Attributes.cpp llvm/lib/Transforms/IPO/IROutliner.cpp Removed: diff --git a/llvm/include/llvm/IR/Attributes.h b/llvm/include/llvm/IR/Attributes.h index bf9595962bd0..fbfe5854594f 100644 --- a/llvm/include/llvm/IR/Attributes.h +++ b/llvm/include/llvm/IR/Attributes.h @@ -951,9 +951,24 @@ AttrBuilder typeIncompatible(Type *Ty); /// attributes for inlining purposes. bool areInlineCompatible(const Function &Caller, const Function &Callee); + +/// Checks if there are any incompatible function attributes between +/// \p A and \p B. +/// +/// \param [in] A - The first function to be compared with. +/// \param [in] B - The second function to be compared with. +/// \returns true if the functions have compatible attributes. +bool areOutlineCompatible(const Function &A, const Function &B); + /// Merge caller's and callee's attributes. void mergeAttributesForInlining(Function &Caller, const Function &Callee); +/// Merges the functions attributes from \p ToMerge into function \p Base. +/// +/// \param [in,out] Base - The function being merged into. +/// \param [in] ToMerge - The function to merge attributes from. +void mergeAttributesForOutlining(Function &Base, const Function &ToMerge); + } // end namespace AttributeFuncs } // end namespace llvm diff --git a/llvm/lib/IR/Attributes.cpp b/llvm/lib/IR/Attributes.cpp index 7001ab82331d..d39cdf7db04e 100644 --- a/llvm/lib/IR/Attributes.cpp +++ b/llvm/lib/IR/Attributes.cpp @@ -2091,7 +2091,25 @@ bool AttributeFuncs::areInlineCompatible(const Function &Caller, return hasCompatibleFnAttrs(Caller, Callee); } +bool AttributeFuncs::areOutlineCompatible(const Function &A, + const Function &B) { + return hasCompatibleFnAttrs(A, B); +} + void AttributeFuncs::mergeAttributesForInlining(Function &Caller, const Function &Callee) { mergeFnAttrs(Caller, Callee); } + +void AttributeFuncs::mergeAttributesForOutlining(Function &Base, +const Function &ToMerge) { + + // We merge functions so that they meet the most general case. + // For example, if the NoNansFPMathAttr is set in one function, but not in + // the other, in the merged function we can say that the NoNansFPMathAttr + // is not set. + // However if we have the SpeculativeLoadHardeningAttr set true in one + // function, but not the other, we make sure that the function retains + // that aspect in the merged function. + mergeFnAttrs(Base, ToMerge); +} diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index 908ba0c70e70..01605769bcff 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -1201,6 +1201,8 @@ void IROutliner::deduplicateExtractedSections( for (unsigned Idx = 1; Idx < CurrentGroup.Regions.size(); Idx++) { CurrentOS = CurrentGroup.Regions[Idx]; +AttributeFuncs::mergeAttributesForOutlining(*CurrentGroup.OutlinedFunction, + *CurrentOS->ExtractedFunction); // Create a new BasicBlock to hold the needed store instructions. BasicBlock *NewBB = BasicBlock::Create( diff --git a/llvm/test/Transforms/IROutliner/outlining-compatible-and-attribute-transfer.ll b/llvm/test/Transforms/IROutliner/outlining-compatible-and-attribute-transfer.ll new file mode 100644 index ..0a051883b069 --- /dev/null +++ b/llvm/test/Transforms/IROutliner/outlining-compatible-and-attribute-transfer.ll @@ -0,0 +1,126 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -verify -iroutliner < %s | FileCheck %s + +; This has two compatible regions based on function attributes. We h
[llvm-branch-commits] [llvm] d974ac0 - [IRSim] Letting gep instructions be legal for similarity identification.
Author: Andrew Litteken Date: 2020-12-31T14:41:14-06:00 New Revision: d974ac0224dec34b95fb1be8c61bd8b524698bcd URL: https://github.com/llvm/llvm-project/commit/d974ac0224dec34b95fb1be8c61bd8b524698bcd DIFF: https://github.com/llvm/llvm-project/commit/d974ac0224dec34b95fb1be8c61bd8b524698bcd.diff LOG: [IRSim] Letting gep instructions be legal for similarity identification. GetElementPtr instructions require the extra check that all operands after the first must only be constants and be exactly the same to be considered similar. Tests are found in unittests/Analysis/IRSimilarityIdentifierTest.cpp. Added: Modified: llvm/include/llvm/Analysis/IRSimilarityIdentifier.h llvm/lib/Analysis/IRSimilarityIdentifier.cpp llvm/test/Transforms/IROutliner/illegal-gep.ll llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp Removed: diff --git a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h index 99a5fcb3a578..a3004ca0dc59 100644 --- a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h +++ b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h @@ -396,10 +396,6 @@ struct IRInstructionMapper { // analyzed for similarity as it has no bearing on the outcome of the // program. InstrType visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return Invisible; } -// TODO: Handle GetElementPtrInsts -InstrType visitGetElementPtrInst(GetElementPtrInst &GEPI) { - return Illegal; -} // TODO: Handle specific intrinsics. InstrType visitIntrinsicInst(IntrinsicInst &II) { return Illegal; } // TODO: Handle CallInsts. diff --git a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp index 141c1e0a5d03..c276e3f28d73 100644 --- a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp +++ b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp @@ -83,27 +83,53 @@ bool IRSimilarity::isClose(const IRInstructionData &A, // Check if we are performing the same sort of operation on the same types // but not on the same values. - if (A.Inst->isSameOperationAs(B.Inst)) -return true; + if (!A.Inst->isSameOperationAs(B.Inst)) { +// If there is a predicate, this means that either there is a swapped +// predicate, or that the types are diff erent, we want to make sure that +// the predicates are equivalent via swapping. +if (isa(A.Inst) && isa(B.Inst)) { + + if (A.getPredicate() != B.getPredicate()) +return false; + + // If the predicates are the same via swap, make sure that the types are + // still the same. + auto ZippedTypes = zip(A.OperVals, B.OperVals); + + return all_of( + ZippedTypes, [](std::tuple R) { +return std::get<0>(R)->getType() == std::get<1>(R)->getType(); + }); +} - // If there is a predicate, this means that either there is a swapped - // predicate, or that the types are diff erent, we want to make sure that - // the predicates are equivalent via swapping. - if (isa(A.Inst) && isa(B.Inst)) { +return false; + } + + // Since any GEP Instruction operands after the first operand cannot be + // defined by a register, we must make sure that the operands after the first + // are the same in the two instructions + if (auto *GEP = dyn_cast(A.Inst)) { +auto *OtherGEP = cast(B.Inst); -if (A.getPredicate() != B.getPredicate()) +// If the instructions do not have the same inbounds restrictions, we do +// not consider them the same. +if (GEP->isInBounds() != OtherGEP->isInBounds()) return false; -// If the predicates are the same via swap, make sure that the types are -// still the same. -auto ZippedTypes = zip(A.OperVals, B.OperVals); +auto ZippedOperands = zip(GEP->indices(), OtherGEP->indices()); -return all_of(ZippedTypes, [](std::tuple R) { - return std::get<0>(R)->getType() == std::get<1>(R)->getType(); -}); +auto ZIt = ZippedOperands.begin(); + +// We increment here since we do not care about the first instruction, +// we only care about the following operands since they must be the +// exact same to be considered similar. +return std::all_of(++ZIt, ZippedOperands.end(), + [](std::tuple R) { + return std::get<0>(R) == std::get<1>(R); + }); } - return false; + return true; } // TODO: This is the same as the MachineOutliner, and should be consolidated diff --git a/llvm/test/Transforms/IROutliner/illegal-gep.ll b/llvm/test/Transforms/IROutliner/illegal-gep.ll index a625106105b0..5f009617c4b3 100644 --- a/llvm/test/Transforms/IROutliner/illegal-gep.ll +++ b/llvm/test/Transforms/IROutliner/illegal-gep.ll @@ -12,7 +12,8 @@ define void @function1(%struct.ST* %s, i64 %t) { ; CHECK-NEXT: entry: ; CHECK-NEXT:[[A:%.*]] = alloca i3
[llvm-branch-commits] [llvm] 14dc69b - Revert "remove pessimizing moves (reported by gcc 10)"
Author: Andrew Litteken Date: 2020-12-31T15:14:11-06:00 New Revision: 14dc69b09218bb580069eb547bb16ab0c43db6d4 URL: https://github.com/llvm/llvm-project/commit/14dc69b09218bb580069eb547bb16ab0c43db6d4 DIFF: https://github.com/llvm/llvm-project/commit/14dc69b09218bb580069eb547bb16ab0c43db6d4.diff LOG: Revert "remove pessimizing moves (reported by gcc 10)" Causing multiple different buildbots to fail with similar errors to: http://lab.llvm.org:8011/#/builders/84/builds/3719/ http://lab.llvm.org:8011/#/builders/21/builds/5863/ This reverts commit a2513cb8655e0aea4baffb4391e946ad3e56d883. Added: Modified: llvm/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h Removed: diff --git a/llvm/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h b/llvm/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h index 63db9d4942bac..1c8b8e0bc922e 100644 --- a/llvm/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h +++ b/llvm/include/llvm/ExecutionEngine/Orc/Shared/RPCUtils.h @@ -1510,20 +1510,20 @@ class SingleThreadedRPCEndpoint Args...)) { detail::ResultTraits::consumeAbandoned( std::move(Result)); - return Err; + return std::move(Err); } if (auto Err = this->C.send()) { detail::ResultTraits::consumeAbandoned( std::move(Result)); - return Err; + return std::move(Err); } while (!ReceivedResponse) { if (auto Err = this->handleOne()) { detail::ResultTraits::consumeAbandoned( std::move(Result)); -return Err; +return std::move(Err); } } ___ llvm-branch-commits mailing list llvm-branch-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits
[llvm-branch-commits] [llvm] b6b1006 - [IRSim][IROutliner] Allowing GEP instructions to be outlined.
Author: Andrew Litteken Date: 2020-12-31T16:54:17-06:00 New Revision: b6b1006f0719481dfb785f281afb5b371c19f00c URL: https://github.com/llvm/llvm-project/commit/b6b1006f0719481dfb785f281afb5b371c19f00c DIFF: https://github.com/llvm/llvm-project/commit/b6b1006f0719481dfb785f281afb5b371c19f00c.diff LOG: [IRSim][IROutliner] Allowing GEP instructions to be outlined. We outline what the IRSimilarityIdentifier deems GEP Instructions to be similar. In this case, the types must be the same, and the operand values after the first indexing operand must be the exact same. Tests: Removing test/Transforms/IROutliner/illegal-gep.ll Adding test/Transforms/IROutliner/outlining-gep.ll Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87317 Added: llvm/test/Transforms/IROutliner/outlining-gep.ll Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h Removed: llvm/test/Transforms/IROutliner/illegal-gep.ll diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index 947a70866b04..fef02b18b7c3 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -318,8 +318,6 @@ class IROutliner { // analyzed for similarity as it has no bearing on the outcome of the // program. bool visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return true; } -// TODO: Handle GetElementPtrInsts -bool visitGetElementPtrInst(GetElementPtrInst &GEPI) { return false; } // TODO: Handle specific intrinsics individually from those that can be // handled. bool IntrinsicInst(IntrinsicInst &II) { return false; } diff --git a/llvm/test/Transforms/IROutliner/illegal-gep.ll b/llvm/test/Transforms/IROutliner/illegal-gep.ll deleted file mode 100644 index 5f009617c4b3.. --- a/llvm/test/Transforms/IROutliner/illegal-gep.ll +++ /dev/null @@ -1,50 +0,0 @@ -; NOTE: Assertions have been autogenerated by utils/update_test_checks.py -; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s - -; This test checks to make sure that we do not outline getelementptr -; instructions since we must make extra checks on the final operands. - -%struct.RT = type { i8, [10 x [20 x i32]], i8 } -%struct.ST = type { i32, double, %struct.RT } - -define void @function1(%struct.ST* %s, i64 %t) { -; CHECK-LABEL: @function1( -; CHECK-NEXT: entry: -; CHECK-NEXT:[[A:%.*]] = alloca i32, align 4 -; CHECK-NEXT:[[B:%.*]] = alloca i32, align 4 -; CHECK-NEXT:store i32 2, i32* [[A]], align 4 -; CHECK-NEXT:store i32 3, i32* [[B]], align 4 -; CHECK-NEXT:[[TMP0:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S:%.*]], i64 1 -; CHECK-NEXT:[[TMP1:%.*]] = getelementptr inbounds [[STRUCT_ST]], %struct.ST* [[S]], i64 [[T:%.*]] -; CHECK-NEXT:ret void -; -entry: - %a = alloca i32, align 4 - %b = alloca i32, align 4 - store i32 2, i32* %a, align 4 - store i32 3, i32* %b, align 4 - %0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1 - %1 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %t - ret void -} - -define void @function2(%struct.ST* %s, i64 %t) { -; CHECK-LABEL: @function2( -; CHECK-NEXT: entry: -; CHECK-NEXT:[[A:%.*]] = alloca i32, align 4 -; CHECK-NEXT:[[B:%.*]] = alloca i32, align 4 -; CHECK-NEXT:store i32 2, i32* [[A]], align 4 -; CHECK-NEXT:store i32 3, i32* [[B]], align 4 -; CHECK-NEXT:[[TMP0:%.*]] = getelementptr inbounds [[STRUCT_ST:%.*]], %struct.ST* [[S:%.*]], i64 1 -; CHECK-NEXT:[[TMP1:%.*]] = getelementptr inbounds [[STRUCT_ST]], %struct.ST* [[S]], i64 [[T:%.*]] -; CHECK-NEXT:ret void -; -entry: - %a = alloca i32, align 4 - %b = alloca i32, align 4 - store i32 2, i32* %a, align 4 - store i32 3, i32* %b, align 4 - %0 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 1 - %1 = getelementptr inbounds %struct.ST, %struct.ST* %s, i64 %t - ret void -} diff --git a/llvm/test/Transforms/IROutliner/outlining-gep.ll b/llvm/test/Transforms/IROutliner/outlining-gep.ll new file mode 100644 index ..3d99e5c8caa3 --- /dev/null +++ b/llvm/test/Transforms/IROutliner/outlining-gep.ll @@ -0,0 +1,68 @@ +; NOTE: Assertions have been autogenerated by utils/update_test_checks.py +; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s + +; This test checks to make sure that we outline getelementptr instructions only +; when all the operands after the first are the exact same. In this case, we +; outline from the first two functions, but not the third. + +%struct.RT = type { i8, [10 x [20 x i32]], i8 } +%struct.ST = type { i32, double, %struct.RT } + +define void @function1(%struct.ST* %s, i64 %t) { +; CHECK-LABEL: @function1( +; CHECK-NEXT: entry: +; CHECK-NEXT:[[A:%.*]] = alloca i32, align 4 +; CHECK-NEXT:[[B:%.*]] = alloca i32, align 4 +; CHECK-NEXT
[llvm-branch-commits] [llvm] 0d21e66 - [IRSim] Letting call instructions be legal for similarity identification.
Author: Andrew Litteken Date: 2020-12-31T20:52:45-06:00 New Revision: 0d21e66014fc5cac1302a148e65d5ad6a41af37b URL: https://github.com/llvm/llvm-project/commit/0d21e66014fc5cac1302a148e65d5ad6a41af37b DIFF: https://github.com/llvm/llvm-project/commit/0d21e66014fc5cac1302a148e65d5ad6a41af37b.diff LOG: [IRSim] Letting call instructions be legal for similarity identification. Here we let non-intrinsic calls be considered legal and valid for similarity only if the call is not indirect, and has a name. For two calls to be considered similar, they must have the same name, the same function types, and the same set of parameters, including tail calls and calling conventions. Tests are found in unittests/Analysis/IRSimilarityIdentifierTest.cpp. Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87312 Added: Modified: llvm/include/llvm/Analysis/IRSimilarityIdentifier.h llvm/lib/Analysis/IRSimilarityIdentifier.cpp llvm/test/Transforms/IROutliner/illegal-calls.ll llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp Removed: diff --git a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h index a3004ca0dc59..9e97541e542b 100644 --- a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h +++ b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h @@ -183,6 +183,12 @@ struct IRInstructionData : ilist_node { llvm::hash_value(ID.Inst->getType()), llvm::hash_value(ID.getPredicate()), llvm::hash_combine_range(OperTypes.begin(), OperTypes.end())); +else if (CallInst *CI = dyn_cast(ID.Inst)) + return llvm::hash_combine( + llvm::hash_value(ID.Inst->getOpcode()), + llvm::hash_value(ID.Inst->getType()), + llvm::hash_value(CI->getCalledFunction()->getName().str()), + llvm::hash_combine_range(OperTypes.begin(), OperTypes.end())); return llvm::hash_combine( llvm::hash_value(ID.Inst->getOpcode()), llvm::hash_value(ID.Inst->getType()), @@ -398,8 +404,14 @@ struct IRInstructionMapper { InstrType visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return Invisible; } // TODO: Handle specific intrinsics. InstrType visitIntrinsicInst(IntrinsicInst &II) { return Illegal; } -// TODO: Handle CallInsts. -InstrType visitCallInst(CallInst &CI) { return Illegal; } +// We only allow call instructions where the function has a name and +// is not an indirect call. +InstrType visitCallInst(CallInst &CI) { + Function *F = CI.getCalledFunction(); + if (!F || CI.isIndirectCall() || !F->hasName()) +return Illegal; + return Legal; +} // TODO: We do not current handle similarity that changes the control flow. InstrType visitInvokeInst(InvokeInst &II) { return Illegal; } // TODO: We do not current handle similarity that changes the control flow. diff --git a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp index c276e3f28d73..60b4f427e189 100644 --- a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp +++ b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp @@ -75,6 +75,12 @@ CmpInst::Predicate IRInstructionData::getPredicate() const { return cast(Inst)->getPredicate(); } +static StringRef getCalledFunctionName(CallInst &CI) { + assert(CI.getCalledFunction() != nullptr && "Called Function is nullptr?"); + + return CI.getCalledFunction()->getName(); +} + bool IRSimilarity::isClose(const IRInstructionData &A, const IRInstructionData &B) { @@ -129,6 +135,16 @@ bool IRSimilarity::isClose(const IRInstructionData &A, }); } + // If the instructions are functions, we make sure that the function name is + // the same. We already know that the types are since is isSameOperationAs is + // true. + if (isa(A.Inst) && isa(B.Inst)) { +CallInst *CIA = cast(A.Inst); +CallInst *CIB = cast(B.Inst); +if (getCalledFunctionName(*CIA).compare(getCalledFunctionName(*CIB)) != 0) + return false; + } + return true; } diff --git a/llvm/test/Transforms/IROutliner/illegal-calls.ll b/llvm/test/Transforms/IROutliner/illegal-calls.ll index 99c8f6fa838d..18d37c2f4dc0 100644 --- a/llvm/test/Transforms/IROutliner/illegal-calls.ll +++ b/llvm/test/Transforms/IROutliner/illegal-calls.ll @@ -13,7 +13,9 @@ define void @outline_constants1() { ; CHECK-NEXT:[[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT:[[B:%.*]] = alloca i32, align 4 ; CHECK-NEXT:[[C:%.*]] = alloca i32, align 4 -; CHECK-NEXT:call void @outlined_ir_func_1(i32* [[A]], i32* [[B]], i32* [[C]]) +; CHECK-NEXT:store i32 2, i32* [[A]], align 4 +; CHECK-NEXT:store i32 3, i32* [[B]], align 4 +; CHECK-NEXT:store i32 4, i32* [[C]], align 4 ; CHECK-NEXT:call void @f1(i32* [[A]], i32* [[B]]) ; CHECK-NEXT
[llvm-branch-commits] [llvm] 57a4691 - [IRSim][IROutliner] Allowing call instructions to be outlined.
Author: Andrew Litteken Date: 2020-12-31T23:01:29-06:00 New Revision: 57a46914f5c1efbdc130dc7a06f8d5b45d606f8d URL: https://github.com/llvm/llvm-project/commit/57a46914f5c1efbdc130dc7a06f8d5b45d606f8d DIFF: https://github.com/llvm/llvm-project/commit/57a46914f5c1efbdc130dc7a06f8d5b45d606f8d.diff LOG: [IRSim][IROutliner] Allowing call instructions to be outlined. We add an extra check to make sure that we do not outline calls to indirect functions, but outline whatever the IRSimilarityIdentifier finds with respect to calls. Tests: Removing test/Transforms/IROutliner/illegal-calls.ll Adding test/Transforms/IROutliner/outlining-calls.ll Adding test/Transforms/IROutliner/illegal-indirect-calls.ll Excluding DebugInfo this is the last patch for the initial implementation of the IROutliner! Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87314 Added: llvm/test/Transforms/IROutliner/illegal-indirect-calls.ll llvm/test/Transforms/IROutliner/outlining-calls.ll Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h Removed: llvm/test/Transforms/IROutliner/illegal-calls.ll diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index fef02b18b7c3..0346803e9ad7 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -321,9 +321,14 @@ class IROutliner { // TODO: Handle specific intrinsics individually from those that can be // handled. bool IntrinsicInst(IntrinsicInst &II) { return false; } -// TODO: Handle CallInsts, there will need to be handling for special kinds -// of calls, as well as calls to intrinsics. -bool visitCallInst(CallInst &CI) { return false; } +// We only handle CallInsts that are not indirect, since we cannot guarantee +// that they have a name in these cases. +bool visitCallInst(CallInst &CI) { + Function *F = CI.getCalledFunction(); + if (!F || CI.isIndirectCall() || !F->hasName()) +return false; + return true; +} // TODO: Handle FreezeInsts. Since a frozen value could be frozen inside // the outlined region, and then returned as an output, this will have to be // handled diff erently. diff --git a/llvm/test/Transforms/IROutliner/illegal-calls.ll b/llvm/test/Transforms/IROutliner/illegal-indirect-calls.ll similarity index 60% rename from llvm/test/Transforms/IROutliner/illegal-calls.ll rename to llvm/test/Transforms/IROutliner/illegal-indirect-calls.ll index 18d37c2f4dc0..513fa60dc625 100644 --- a/llvm/test/Transforms/IROutliner/illegal-calls.ll +++ b/llvm/test/Transforms/IROutliner/illegal-indirect-calls.ll @@ -1,22 +1,21 @@ ; NOTE: Assertions have been autogenerated by utils/update_test_checks.py ; RUN: opt -S -verify -iroutliner -ir-outlining-no-cost < %s | FileCheck %s -; This test checks that we do not outline calls. Special calls, such as -; indirect or nameless calls require extra handling to ensure that there -; are no inconsistencies when outlining and consolidating regions. +; This test checks that we do not outline indirect calls. We cannot guarantee +; that we have the same name in these cases, so two indirect calls cannot +; be considered similar. declare void @f1(i32*, i32*); +declare void @f2(i32*, i32*); -define void @outline_constants1() { -; CHECK-LABEL: @outline_constants1( +define void @function1(void()* %func) { +; CHECK-LABEL: @function1( ; CHECK-NEXT: entry: ; CHECK-NEXT:[[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT:[[B:%.*]] = alloca i32, align 4 ; CHECK-NEXT:[[C:%.*]] = alloca i32, align 4 -; CHECK-NEXT:store i32 2, i32* [[A]], align 4 -; CHECK-NEXT:store i32 3, i32* [[B]], align 4 -; CHECK-NEXT:store i32 4, i32* [[C]], align 4 -; CHECK-NEXT:call void @f1(i32* [[A]], i32* [[B]]) +; CHECK-NEXT:call void @outlined_ir_func_1(i32* [[A]], i32* [[B]], i32* [[C]]) +; CHECK-NEXT:call void [[FUNC:%.*]]() ; CHECK-NEXT:call void @outlined_ir_func_0(i32* [[A]], i32* [[B]], i32* [[C]]) ; CHECK-NEXT:ret void ; @@ -27,23 +26,21 @@ entry: store i32 2, i32* %a, align 4 store i32 3, i32* %b, align 4 store i32 4, i32* %c, align 4 - call void @f1(i32* %a, i32* %b) + call void %func() %al = load i32, i32* %a %bl = load i32, i32* %b %cl = load i32, i32* %c ret void } -define void @outline_constants2() { -; CHECK-LABEL: @outline_constants2( +define void @function2(void()* %func) { +; CHECK-LABEL: @function2( ; CHECK-NEXT: entry: ; CHECK-NEXT:[[A:%.*]] = alloca i32, align 4 ; CHECK-NEXT:[[B:%.*]] = alloca i32, align 4 ; CHECK-NEXT:[[C:%.*]] = alloca i32, align 4 -; CHECK-NEXT:store i32 2, i32* [[A]], align 4 -; CHECK-NEXT:store i32 3, i32* [[B]], align 4 -; CHECK-NEXT:store i32 4, i32* [[C]], align 4 -; CHECK-NEXT:call void @f1(i32* [[A]
[llvm-branch-commits] [llvm] 05e6ac4 - [IROutliner] Removing a duplicate addition, causing overestimates in IROutliner.
Author: Andrew Litteken Date: 2021-01-03T23:36:28-06:00 New Revision: 05e6ac4eb811f332ece873381561b0fad0974256 URL: https://github.com/llvm/llvm-project/commit/05e6ac4eb811f332ece873381561b0fad0974256 DIFF: https://github.com/llvm/llvm-project/commit/05e6ac4eb811f332ece873381561b0fad0974256.diff LOG: [IROutliner] Removing a duplicate addition, causing overestimates in IROutliner. There was an extra addition left over from a previous commit for the cost model, this removes it. Added: Modified: llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/opt-remarks.ll llvm/test/Transforms/IROutliner/outlining-calls.ll llvm/test/Transforms/IROutliner/outlining-compatible-and-attribute-transfer.ll llvm/test/Transforms/IROutliner/outlining-compatible-or-attribute-transfer.ll llvm/test/Transforms/IROutliner/outlining-different-constants.ll llvm/test/Transforms/IROutliner/outlining-different-structure.ll llvm/test/Transforms/IROutliner/outlining-isomorphic-predicates.ll Removed: diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index e506d84b2c29..3acde6b6ece0 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -1286,7 +1286,6 @@ unsigned IROutliner::findBenefitFromAllRegions(OutlinableGroup &CurrentGroup) { RegionBenefit += Region->getBenefit(TTI); LLVM_DEBUG(dbgs() << "Adding: " << RegionBenefit << " saved instructions to overfall benefit.\n"); -CurrentGroup.Benefit += RegionBenefit; } return RegionBenefit; @@ -1405,7 +1404,8 @@ void IROutliner::findCostBenefit(Module &M, OutlinableGroup &CurrentGroup) { LLVM_DEBUG(dbgs() << "Adding: " << OverallArgumentNum << " instructions to cost for each argument in the new" << " function.\n"); - CurrentGroup.Cost += 2 * OverallArgumentNum * TargetTransformInfo::TCC_Basic; + CurrentGroup.Cost += + NumRegions * OverallArgumentNum * TargetTransformInfo::TCC_Basic; LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n"); // Each argument needs to either be loaded into a register or onto the stack. @@ -1416,7 +1416,7 @@ void IROutliner::findCostBenefit(Module &M, OutlinableGroup &CurrentGroup) { << " function " << NumRegions << " times for the " << "needed argument handling at the call site.\n"); CurrentGroup.Cost += - 2 * OverallArgumentNum * TargetTransformInfo::TCC_Basic * NumRegions; + OverallArgumentNum * TargetTransformInfo::TCC_Basic * NumRegions; LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n"); CurrentGroup.Cost += findCostForOutputBlocks(M, CurrentGroup, TTI); diff --git a/llvm/test/Transforms/IROutliner/opt-remarks.ll b/llvm/test/Transforms/IROutliner/opt-remarks.ll index 0658aba18f6e..2a26e5b08784 100644 --- a/llvm/test/Transforms/IROutliner/opt-remarks.ll +++ b/llvm/test/Transforms/IROutliner/opt-remarks.ll @@ -5,13 +5,16 @@ ; RUN: -pass-remarks-output=%t < %s ; RUN: cat %t | FileCheck -check-prefix=YAML %s -; CHECK: remark: :0:0: outlined 2 regions with decrease of 31 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 5 instructions at locations +; CHECK: remark: :0:0: outlined 2 regions with decrease of 2 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 6 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 7 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 8 instructions at locations ; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 9 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 13 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 17 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 21 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 10 instructions at locations ; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 7 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 8 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 13 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 10 instructions at locations ; YAML: --- !Passed ; YAML-NEXT: Pass:iroutli
[llvm-branch-commits] [llvm] 5c95162 - [IROutliner] Refactoring errors in the cost model from past patches.
Author: Andrew Litteken Date: 2021-01-04T00:11:18-06:00 New Revision: 5c951623bc8965fa1e89660f2f5f4a2944e4981a URL: https://github.com/llvm/llvm-project/commit/5c951623bc8965fa1e89660f2f5f4a2944e4981a DIFF: https://github.com/llvm/llvm-project/commit/5c951623bc8965fa1e89660f2f5f4a2944e4981a.diff LOG: [IROutliner] Refactoring errors in the cost model from past patches. There were was the reuse of a variable that should not have been occurred due to confusion during committing patches. Added: Modified: llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/opt-remarks.ll llvm/test/Transforms/IROutliner/outlining-cost-model.ll Removed: diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index 3acde6b6ece0..0e5e1dd0886e 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -1405,7 +1405,7 @@ void IROutliner::findCostBenefit(Module &M, OutlinableGroup &CurrentGroup) { << " instructions to cost for each argument in the new" << " function.\n"); CurrentGroup.Cost += - NumRegions * OverallArgumentNum * TargetTransformInfo::TCC_Basic; + OverallArgumentNum * TargetTransformInfo::TCC_Basic; LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n"); // Each argument needs to either be loaded into a register or onto the stack. @@ -1416,7 +1416,7 @@ void IROutliner::findCostBenefit(Module &M, OutlinableGroup &CurrentGroup) { << " function " << NumRegions << " times for the " << "needed argument handling at the call site.\n"); CurrentGroup.Cost += - OverallArgumentNum * TargetTransformInfo::TCC_Basic * NumRegions; + 2 * OverallArgumentNum * TargetTransformInfo::TCC_Basic * NumRegions; LLVM_DEBUG(dbgs() << "Current Cost: " << CurrentGroup.Cost << "\n"); CurrentGroup.Cost += findCostForOutputBlocks(M, CurrentGroup, TTI); diff --git a/llvm/test/Transforms/IROutliner/opt-remarks.ll b/llvm/test/Transforms/IROutliner/opt-remarks.ll index 2a26e5b08784..7172908a84a8 100644 --- a/llvm/test/Transforms/IROutliner/opt-remarks.ll +++ b/llvm/test/Transforms/IROutliner/opt-remarks.ll @@ -5,18 +5,48 @@ ; RUN: -pass-remarks-output=%t < %s ; RUN: cat %t | FileCheck -check-prefix=YAML %s -; CHECK: remark: :0:0: outlined 2 regions with decrease of 2 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 6 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 7 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 8 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 9 instructions at locations +; CHECK: remark: :0:0: did not outline 2 regions due to estimated increase of 12 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 5 instructions at locations +; CHECK-NEXT: remark: :0:0: outlined 2 regions with decrease of 2 instructions at locations ; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 10 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 7 instructions at locations -; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 8 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 11 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 12 instructions at locations ; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 13 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 14 instructions at locations ; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 10 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 11 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 17 instructions at locations +; CHECK-NEXT: remark: :0:0: did not outline 2 regions due to estimated increase of 13 instructions at locations -; YAML: --- !Passed +; YAML: --- !Missed +; YAML-NEXT: Pass:iroutliner +; YAML-NEXT: Name:WouldNotDecreaseSize +; YAML-NEXT: Function:function3 +; YAML-NEXT: Args: +; YAML-NEXT: - String: 'did not outline ' +; YAML-NEXT: - String: '2' +; YAML-NEXT: - String: ' regions due to estimated increase of ' +; YAML-NEXT: - Instruct
[llvm-branch-commits] [llvm] dae3446 - [IRSim][IROutliner] Adding the extraction basics for the IROutliner.
Author: Andrew Litteken Date: 2020-12-17T11:27:26-06:00 New Revision: dae34463e3e05a055899b65251efde887a24ec38 URL: https://github.com/llvm/llvm-project/commit/dae34463e3e05a055899b65251efde887a24ec38 DIFF: https://github.com/llvm/llvm-project/commit/dae34463e3e05a055899b65251efde887a24ec38.diff LOG: [IRSim][IROutliner] Adding the extraction basics for the IROutliner. Extracting the similar regions is the first step in the IROutliner. Using the IRSimilarityIdentifier, we collect the SimilarityGroups and sort them by how many instructions will be removed. Each IRSimilarityCandidate is used to define an OutlinableRegion. Each region is ordered by their occurrence in the Module and the regions that are not compatible with previously outlined regions are discarded. Each region is then extracted with the CodeExtractor into its own function. We test that correctly extract in: test/Transforms/IROutliner/extraction.ll test/Transforms/IROutliner/address-taken.ll test/Transforms/IROutliner/outlining-same-globals.ll test/Transforms/IROutliner/outlining-same-constants.ll test/Transforms/IROutliner/outlining-different-structure.ll Recommit of bf899e891387d07dfd12de195ce2a16f62afd5e0 fixing memory leaks. Reviewers: paquette, jroelofs, yroux Differential Revision: https://reviews.llvm.org/D86975 Added: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/outlining-address-taken.ll llvm/test/Transforms/IROutliner/outlining-different-structure.ll llvm/test/Transforms/IROutliner/outlining-same-constants.ll llvm/test/Transforms/IROutliner/outlining-same-globals.ll Modified: llvm/include/llvm/InitializePasses.h llvm/include/llvm/Transforms/IPO.h llvm/lib/Passes/PassBuilder.cpp llvm/lib/Passes/PassRegistry.def llvm/lib/Transforms/IPO/CMakeLists.txt llvm/lib/Transforms/IPO/IPO.cpp llvm/lib/Transforms/IPO/PassManagerBuilder.cpp Removed: diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index e1b3a8dd3f3a..f77de64e2c64 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -184,6 +184,7 @@ void initializeHotColdSplittingLegacyPassPass(PassRegistry&); void initializeHWAddressSanitizerLegacyPassPass(PassRegistry &); void initializeIPSCCPLegacyPassPass(PassRegistry&); void initializeIRCELegacyPassPass(PassRegistry&); +void initializeIROutlinerLegacyPassPass(PassRegistry&); void initializeIRSimilarityIdentifierWrapperPassPass(PassRegistry&); void initializeIRTranslatorPass(PassRegistry&); void initializeIVUsersWrapperPassPass(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/IPO.h b/llvm/include/llvm/Transforms/IPO.h index 1918ad76a270..af357181597a 100644 --- a/llvm/include/llvm/Transforms/IPO.h +++ b/llvm/include/llvm/Transforms/IPO.h @@ -215,6 +215,11 @@ ModulePass *createMergeFunctionsPass(); /// function(s). ModulePass *createHotColdSplittingPass(); +//===--===// +/// createIROutlinerPass - This pass finds similar code regions and factors +/// those regions out into functions. +ModulePass *createIROutlinerPass(); + //===--===// /// createPartialInliningPass - This pass inlines parts of functions. /// diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h new file mode 100644 index ..80ba40d91ed8 --- /dev/null +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -0,0 +1,191 @@ +//===- IROutliner.h - Extract similar IR regions into functions ==// +// +// 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 +// +//===--===// +// +// \file +// The interface file for the IROutliner which is used by the IROutliner Pass. +// +// The outliner uses the IRSimilarityIdentifier to identify the similar regions +// of code. It evaluates each set of IRSimilarityCandidates with an estimate of +// whether it will provide code size reduction. Each region is extracted using +// the code extractor. These extracted functions are consolidated into a single +// function and called from the extracted call site. +// +// For example: +// \code +// %1 = add i32 %a, %b +// %2 = add i32 %b, %a +// %3 = add i32 %b, %a +// %4 = add i32 %a, %b +// \endcode +// would become function +// \code +// define internal void outlined_ir_function(i32 %0, i32 %1) { +// %1 = add i32 %0, %1 +// %2 = add i32 %1, %0 +// ret void +// } +// \endcode +// with
[llvm-branch-commits] [llvm] cea8076 - [IRSim][IROutliner] Adding InstVisitor to disallow certain operations.
Author: Andrew Litteken Date: 2020-12-17T19:33:57-06:00 New Revision: cea807602a2fb0b8d79b0eef30ce717ae4645fbc URL: https://github.com/llvm/llvm-project/commit/cea807602a2fb0b8d79b0eef30ce717ae4645fbc DIFF: https://github.com/llvm/llvm-project/commit/cea807602a2fb0b8d79b0eef30ce717ae4645fbc.diff LOG: [IRSim][IROutliner] Adding InstVisitor to disallow certain operations. This adds a custom InstVisitor to return false on instructions that should not be allowed to be outlined. These match the illegal instructions in the IRInstructionMapper with exception of the addition of the llvm.assume intrinsic. Tests all the tests marked: illegal-*-.ll with a test for each kind of instruction that has been marked as illegal. Reviewers: jroelofs, paquette Differential Revisions: https://reviews.llvm.org/D86976 Added: llvm/test/Transforms/IROutliner/illegal-allocas.ll llvm/test/Transforms/IROutliner/illegal-assumes.ll llvm/test/Transforms/IROutliner/illegal-branches.ll llvm/test/Transforms/IROutliner/illegal-callbr.ll llvm/test/Transforms/IROutliner/illegal-calls.ll llvm/test/Transforms/IROutliner/illegal-catchpad.ll llvm/test/Transforms/IROutliner/illegal-cleanup.ll llvm/test/Transforms/IROutliner/illegal-frozen.ll llvm/test/Transforms/IROutliner/illegal-gep.ll llvm/test/Transforms/IROutliner/illegal-invoke.ll llvm/test/Transforms/IROutliner/illegal-landingpad.ll llvm/test/Transforms/IROutliner/illegal-memcpy.ll llvm/test/Transforms/IROutliner/illegal-memmove.ll llvm/test/Transforms/IROutliner/illegal-memset.ll llvm/test/Transforms/IROutliner/illegal-phi-nodes.ll llvm/test/Transforms/IROutliner/illegal-vaarg.ll llvm/test/Transforms/IROutliner/legal-debug.ll Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp Removed: diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index 80ba40d91ed8..b49970e7056d 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -178,6 +178,61 @@ class IROutliner { /// The memory allocator used to allocate new IRInstructionData. SpecificBumpPtrAllocator InstDataAllocator; + + /// Custom InstVisitor to classify diff erent instructions for whether it can + /// be analyzed for similarity. This is needed as there may be instruction we + /// can identify as having similarity, but are more complicated to outline. + struct InstructionAllowed + : public InstVisitor { +InstructionAllowed() {} + +// TODO: Determine a scheme to resolve when the label is similar enough. +bool visitBranchInst(BranchInst &BI) { return false; } +// TODO: Determine a scheme to resolve when the labels are similar enough. +bool visitPHINode(PHINode &PN) { return false; } +// TODO: Handle allocas. +bool visitAllocaInst(AllocaInst &AI) { return false; } +// VAArg instructions are not allowed since this could cause diff iculty when +// diff erentiating between diff erent sets of variable instructions in +// the deduplicated outlined regions. +bool visitVAArgInst(VAArgInst &VI) { return false; } +// We exclude all exception handling cases since they are so context +// dependent. +bool visitLandingPadInst(LandingPadInst &LPI) { return false; } +bool visitFuncletPadInst(FuncletPadInst &FPI) { return false; } +// DebugInfo should be included in the regions, but should not be +// analyzed for similarity as it has no bearing on the outcome of the +// program. +bool visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { + return true; +} +// TODO: Handle GetElementPtrInsts +bool visitGetElementPtrInst(GetElementPtrInst &GEPI) { + return false; +} +// TODO: Handle specific intrinsics individually from those that can be +// handled. +bool IntrinsicInst(IntrinsicInst &II) { return false; } +// TODO: Handle CallInsts, there will need to be handling for special kinds +// of calls, as well as calls to intrinsics. +bool visitCallInst(CallInst &CI) { return false; } +// TODO: Handle FreezeInsts. Since a frozen value could be frozen inside +// the outlined region, and then returned as an output, this will have to be +// handled diff erently. +bool visitFreezeInst(FreezeInst &CI) { return false; } +// TODO: We do not current handle similarity that changes the control flow. +bool visitInvokeInst(InvokeInst &II) { return false; } +// TODO: We do not current handle similarity that changes the control flow. +bool visitCallBrInst(CallBrInst &CBI) { return false; } +// TODO: Handle interblock similarity. +bool visitTerminator(Instruction &I) { return false; } +bool visitInstruction(Instruction &I) { + return true; +} + }; + + /
[llvm-branch-commits] [llvm] c52bcf3 - [IRSim][IROutliner] Limit to extracting regions that only require
Author: Andrew Litteken Date: 2020-12-19T13:33:54-06:00 New Revision: c52bcf3a9b2d3cd60e62f38218979b781ccc9d8a URL: https://github.com/llvm/llvm-project/commit/c52bcf3a9b2d3cd60e62f38218979b781ccc9d8a DIFF: https://github.com/llvm/llvm-project/commit/c52bcf3a9b2d3cd60e62f38218979b781ccc9d8a.diff LOG: [IRSim][IROutliner] Limit to extracting regions that only require inputs. Extracted regions can have both inputs and outputs. In addition, the CodeExtractor removes inputs that are only used in llvm.assumes, and sunken allocas (values are used entirely in the extracted region as denoted by lifetime intrinsics). We also cannot combine sections that have different constants in the same structural location, and these constants will have to elevated to argument. This patch limits the extracted regions to those that only require inputs, and do not have any other special cases. We test that we do not outline the wrong constants in: test/Transforms/IROutliner/outliner-different-constants.ll test/Transforms/IROutliner/outliner-different-globals.ll test/Transforms/IROutliner/outliner-constant-vs-registers.ll We test that correctly outline in: test/Transforms/IROutliner/outlining-same-globals.ll test/Transforms/IROutliner/outlining-same-constants.ll test/Transforms/IROutliner/outlining-different-structure.ll Reviewers: paquette, plofti Differential Revision: https://reviews.llvm.org/D86977 Added: llvm/test/Transforms/IROutliner/outlining-constants-vs-registers.ll llvm/test/Transforms/IROutliner/outlining-different-constants.ll llvm/test/Transforms/IROutliner/outlining-different-globals.ll Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/illegal-assumes.ll llvm/test/Transforms/IROutliner/illegal-memcpy.ll llvm/test/Transforms/IROutliner/illegal-memmove.ll llvm/test/Transforms/IROutliner/illegal-vaarg.ll llvm/test/Transforms/IROutliner/outlining-different-structure.ll llvm/test/Transforms/IROutliner/outlining-same-constants.ll Removed: diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index b49970e7056d..25e42e1b1089 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -154,6 +154,13 @@ class IROutliner { pruneIncompatibleRegions(std::vector &CandidateVec, OutlinableGroup &CurrentGroup); + /// Identify the needed extracted inputs in a section, and add to the overall + /// function if needed. + /// + /// \param [in] M - The module to outline from. + /// \param [in,out] Region - The region to be extracted + void findAddInputsOutputs(Module &M, OutlinableRegion &Region); + /// Extract \p Region into its own function. /// /// \param [in] Region - The region to be extracted into its own function. @@ -182,8 +189,7 @@ class IROutliner { /// Custom InstVisitor to classify diff erent instructions for whether it can /// be analyzed for similarity. This is needed as there may be instruction we /// can identify as having similarity, but are more complicated to outline. - struct InstructionAllowed - : public InstVisitor { + struct InstructionAllowed : public InstVisitor { InstructionAllowed() {} // TODO: Determine a scheme to resolve when the label is similar enough. @@ -203,13 +209,9 @@ class IROutliner { // DebugInfo should be included in the regions, but should not be // analyzed for similarity as it has no bearing on the outcome of the // program. -bool visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { - return true; -} +bool visitDbgInfoIntrinsic(DbgInfoIntrinsic &DII) { return true; } // TODO: Handle GetElementPtrInsts -bool visitGetElementPtrInst(GetElementPtrInst &GEPI) { - return false; -} +bool visitGetElementPtrInst(GetElementPtrInst &GEPI) { return false; } // TODO: Handle specific intrinsics individually from those that can be // handled. bool IntrinsicInst(IntrinsicInst &II) { return false; } @@ -226,9 +228,7 @@ class IROutliner { bool visitCallBrInst(CallBrInst &CBI) { return false; } // TODO: Handle interblock similarity. bool visitTerminator(Instruction &I) { return false; } -bool visitInstruction(Instruction &I) { - return true; -} +bool visitInstruction(Instruction &I) { return true; } }; /// A InstVisitor used to exclude certain instructions from being outlined. diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index 9985d9a09d64..7a1fdd4df1d2 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -41,6 +41,13 @@ struct OutlinableGroup { /// Flag fo
[llvm-branch-commits] [llvm] 5cdc4f5 - [IROutliner] Deduplicating functions that only require inputs.
Author: Andrew Litteken Date: 2020-12-19T17:26:29-06:00 New Revision: 5cdc4f57e50bbe0d211c109517c17defe78e0b73 URL: https://github.com/llvm/llvm-project/commit/5cdc4f57e50bbe0d211c109517c17defe78e0b73 DIFF: https://github.com/llvm/llvm-project/commit/5cdc4f57e50bbe0d211c109517c17defe78e0b73.diff LOG: [IROutliner] Deduplicating functions that only require inputs. Extracted regions can have both inputs and outputs. In addition, the CodeExtractor removes inputs that are only used in llvm.assumes, and sunken allocas (values are used entirely in the extracted region as denoted by lifetime intrinsics). We also cannot combine sections that have different constants in the same structural location, and these constants will have to elevated to argument. This patch deduplicates extracted functions that only have inputs and non of the special cases. We test that correctly deduplicate in: test/Transforms/IROutliner/outlining-same-globals.ll test/Transforms/IROutliner/outlining-same-constants.ll test/Transforms/IROutliner/outlining-different-structure.ll Added: Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/illegal-assumes.ll llvm/test/Transforms/IROutliner/illegal-branches.ll llvm/test/Transforms/IROutliner/illegal-callbr.ll llvm/test/Transforms/IROutliner/illegal-calls.ll llvm/test/Transforms/IROutliner/illegal-catchpad.ll llvm/test/Transforms/IROutliner/illegal-cleanup.ll llvm/test/Transforms/IROutliner/illegal-frozen.ll llvm/test/Transforms/IROutliner/illegal-gep.ll llvm/test/Transforms/IROutliner/illegal-invoke.ll llvm/test/Transforms/IROutliner/illegal-landingpad.ll llvm/test/Transforms/IROutliner/illegal-memset.ll llvm/test/Transforms/IROutliner/illegal-phi-nodes.ll llvm/test/Transforms/IROutliner/legal-debug.ll llvm/test/Transforms/IROutliner/outlining-address-taken.ll llvm/test/Transforms/IROutliner/outlining-different-constants.ll llvm/test/Transforms/IROutliner/outlining-different-structure.ll llvm/test/Transforms/IROutliner/outlining-same-constants.ll llvm/test/Transforms/IROutliner/outlining-same-globals.ll Removed: diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index 25e42e1b1089..01f870097972 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -70,6 +70,17 @@ struct OutlinableRegion { IRInstructionData *NewFront = nullptr; IRInstructionData *NewBack = nullptr; + /// The number of extracted inputs from the CodeExtractor. + unsigned NumExtractedInputs; + + /// Mapping the extracted argument number to the argument number in the + /// overall function. Since there will be inputs, such as elevated constants + /// that are not the same in each region in a SimilarityGroup, or values that + /// cannot be sunk into the extracted section in every region, we must keep + /// track of which extracted argument maps to which overall argument. + DenseMap ExtractedArgToAgg; + DenseMap AggArgToExtracted; + /// Used to create an outlined function. CodeExtractor *CE = nullptr; @@ -154,6 +165,17 @@ class IROutliner { pruneIncompatibleRegions(std::vector &CandidateVec, OutlinableGroup &CurrentGroup); + /// Create the function based on the overall types found in the current + /// regions being outlined. + /// + /// \param M - The module to outline from. + /// \param [in,out] CG - The OutlinableGroup for the regions to be outlined. + /// \param [in] FunctionNameSuffix - How many functions have we previously + /// created. + /// \returns the newly created function. + Function *createFunction(Module &M, OutlinableGroup &CG, + unsigned FunctionNameSuffix); + /// Identify the needed extracted inputs in a section, and add to the overall /// function if needed. /// @@ -167,6 +189,19 @@ class IROutliner { /// \returns True if it was successfully outlined. bool extractSection(OutlinableRegion &Region); + /// For the similarities found, and the extracted sections, create a single + /// outlined function with appropriate output blocks as necessary. + /// + /// \param [in] M - The module to outline from + /// \param [in] CurrentGroup - The set of extracted sections to consolidate. + /// \param [in,out] FuncsToRemove - List of functions to remove from the + /// module after outlining is completed. + /// \param [in,out] OutlinedFunctionNum - the number of new outlined + /// functions. + void deduplicateExtractedSections(Module &M, OutlinableGroup &CurrentGroup, +std::vector &FuncsToRemove, +unsigned &OutlinedFunctionNu
[llvm-branch-commits] [llvm] 7c6f28a - [IROutliner] Deduplicating functions that only require inputs.
Author: Andrew Litteken Date: 2020-12-19T17:34:34-06:00 New Revision: 7c6f28a438b59dea11a7fc2562b3389874c58112 URL: https://github.com/llvm/llvm-project/commit/7c6f28a438b59dea11a7fc2562b3389874c58112 DIFF: https://github.com/llvm/llvm-project/commit/7c6f28a438b59dea11a7fc2562b3389874c58112.diff LOG: [IROutliner] Deduplicating functions that only require inputs. Extracted regions can have both inputs and outputs. In addition, the CodeExtractor removes inputs that are only used in llvm.assumes, and sunken allocas (values are used entirely in the extracted region as denoted by lifetime intrinsics). We also cannot combine sections that have different constants in the same structural location, and these constants will have to elevated to argument. This patch deduplicates extracted functions that only have inputs and non of the special cases. We test that correctly deduplicate in: test/Transforms/IROutliner/outlining-same-globals.ll test/Transforms/IROutliner/outlining-same-constants.ll test/Transforms/IROutliner/outlining-different-structure.ll Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D86978 Added: Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/illegal-assumes.ll llvm/test/Transforms/IROutliner/illegal-branches.ll llvm/test/Transforms/IROutliner/illegal-callbr.ll llvm/test/Transforms/IROutliner/illegal-calls.ll llvm/test/Transforms/IROutliner/illegal-catchpad.ll llvm/test/Transforms/IROutliner/illegal-cleanup.ll llvm/test/Transforms/IROutliner/illegal-frozen.ll llvm/test/Transforms/IROutliner/illegal-gep.ll llvm/test/Transforms/IROutliner/illegal-invoke.ll llvm/test/Transforms/IROutliner/illegal-landingpad.ll llvm/test/Transforms/IROutliner/illegal-memset.ll llvm/test/Transforms/IROutliner/illegal-phi-nodes.ll llvm/test/Transforms/IROutliner/legal-debug.ll llvm/test/Transforms/IROutliner/outlining-address-taken.ll llvm/test/Transforms/IROutliner/outlining-different-constants.ll llvm/test/Transforms/IROutliner/outlining-different-structure.ll llvm/test/Transforms/IROutliner/outlining-same-constants.ll llvm/test/Transforms/IROutliner/outlining-same-globals.ll Removed: diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index 25e42e1b1089..01f870097972 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -70,6 +70,17 @@ struct OutlinableRegion { IRInstructionData *NewFront = nullptr; IRInstructionData *NewBack = nullptr; + /// The number of extracted inputs from the CodeExtractor. + unsigned NumExtractedInputs; + + /// Mapping the extracted argument number to the argument number in the + /// overall function. Since there will be inputs, such as elevated constants + /// that are not the same in each region in a SimilarityGroup, or values that + /// cannot be sunk into the extracted section in every region, we must keep + /// track of which extracted argument maps to which overall argument. + DenseMap ExtractedArgToAgg; + DenseMap AggArgToExtracted; + /// Used to create an outlined function. CodeExtractor *CE = nullptr; @@ -154,6 +165,17 @@ class IROutliner { pruneIncompatibleRegions(std::vector &CandidateVec, OutlinableGroup &CurrentGroup); + /// Create the function based on the overall types found in the current + /// regions being outlined. + /// + /// \param M - The module to outline from. + /// \param [in,out] CG - The OutlinableGroup for the regions to be outlined. + /// \param [in] FunctionNameSuffix - How many functions have we previously + /// created. + /// \returns the newly created function. + Function *createFunction(Module &M, OutlinableGroup &CG, + unsigned FunctionNameSuffix); + /// Identify the needed extracted inputs in a section, and add to the overall /// function if needed. /// @@ -167,6 +189,19 @@ class IROutliner { /// \returns True if it was successfully outlined. bool extractSection(OutlinableRegion &Region); + /// For the similarities found, and the extracted sections, create a single + /// outlined function with appropriate output blocks as necessary. + /// + /// \param [in] M - The module to outline from + /// \param [in] CurrentGroup - The set of extracted sections to consolidate. + /// \param [in,out] FuncsToRemove - List of functions to remove from the + /// module after outlining is completed. + /// \param [in,out] OutlinedFunctionNum - the number of new outlined + /// functions. + void deduplicateExtractedSections(Module &M, OutlinableGroup &CurrentGroup, +std::v
[llvm-branch-commits] [llvm] b8a2b6a - Revert "[IROutliner] Deduplicating functions that only require inputs."
Author: Andrew Litteken Date: 2020-12-19T17:33:49-06:00 New Revision: b8a2b6af374e9dca3ad320fcffd8798c0170801f URL: https://github.com/llvm/llvm-project/commit/b8a2b6af374e9dca3ad320fcffd8798c0170801f DIFF: https://github.com/llvm/llvm-project/commit/b8a2b6af374e9dca3ad320fcffd8798c0170801f.diff LOG: Revert "[IROutliner] Deduplicating functions that only require inputs." Missing reviewers and differential revision in commit message. This reverts commit 5cdc4f57e50bbe0d211c109517c17defe78e0b73. Added: Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/illegal-assumes.ll llvm/test/Transforms/IROutliner/illegal-branches.ll llvm/test/Transforms/IROutliner/illegal-callbr.ll llvm/test/Transforms/IROutliner/illegal-calls.ll llvm/test/Transforms/IROutliner/illegal-catchpad.ll llvm/test/Transforms/IROutliner/illegal-cleanup.ll llvm/test/Transforms/IROutliner/illegal-frozen.ll llvm/test/Transforms/IROutliner/illegal-gep.ll llvm/test/Transforms/IROutliner/illegal-invoke.ll llvm/test/Transforms/IROutliner/illegal-landingpad.ll llvm/test/Transforms/IROutliner/illegal-memset.ll llvm/test/Transforms/IROutliner/illegal-phi-nodes.ll llvm/test/Transforms/IROutliner/legal-debug.ll llvm/test/Transforms/IROutliner/outlining-address-taken.ll llvm/test/Transforms/IROutliner/outlining-different-constants.ll llvm/test/Transforms/IROutliner/outlining-different-structure.ll llvm/test/Transforms/IROutliner/outlining-same-constants.ll llvm/test/Transforms/IROutliner/outlining-same-globals.ll Removed: diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index 01f870097972..25e42e1b1089 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -70,17 +70,6 @@ struct OutlinableRegion { IRInstructionData *NewFront = nullptr; IRInstructionData *NewBack = nullptr; - /// The number of extracted inputs from the CodeExtractor. - unsigned NumExtractedInputs; - - /// Mapping the extracted argument number to the argument number in the - /// overall function. Since there will be inputs, such as elevated constants - /// that are not the same in each region in a SimilarityGroup, or values that - /// cannot be sunk into the extracted section in every region, we must keep - /// track of which extracted argument maps to which overall argument. - DenseMap ExtractedArgToAgg; - DenseMap AggArgToExtracted; - /// Used to create an outlined function. CodeExtractor *CE = nullptr; @@ -165,17 +154,6 @@ class IROutliner { pruneIncompatibleRegions(std::vector &CandidateVec, OutlinableGroup &CurrentGroup); - /// Create the function based on the overall types found in the current - /// regions being outlined. - /// - /// \param M - The module to outline from. - /// \param [in,out] CG - The OutlinableGroup for the regions to be outlined. - /// \param [in] FunctionNameSuffix - How many functions have we previously - /// created. - /// \returns the newly created function. - Function *createFunction(Module &M, OutlinableGroup &CG, - unsigned FunctionNameSuffix); - /// Identify the needed extracted inputs in a section, and add to the overall /// function if needed. /// @@ -189,19 +167,6 @@ class IROutliner { /// \returns True if it was successfully outlined. bool extractSection(OutlinableRegion &Region); - /// For the similarities found, and the extracted sections, create a single - /// outlined function with appropriate output blocks as necessary. - /// - /// \param [in] M - The module to outline from - /// \param [in] CurrentGroup - The set of extracted sections to consolidate. - /// \param [in,out] FuncsToRemove - List of functions to remove from the - /// module after outlining is completed. - /// \param [in,out] OutlinedFunctionNum - the number of new outlined - /// functions. - void deduplicateExtractedSections(Module &M, OutlinableGroup &CurrentGroup, -std::vector &FuncsToRemove, -unsigned &OutlinedFunctionNum); - /// The set of outlined Instructions, identified by their location in the /// sequential ordering of instructions in a Module. DenseSet Outlined; diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index 4031eedced7c..7a1fdd4df1d2 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -38,26 +38,10 @@ struct OutlinableGroup { /// The sections that could be outlined std::vector Regions; - /// The argument types for the function created as the o
[llvm-branch-commits] [llvm] b1191c8 - [IROutliner] Adding support for elevating constants that are not the same in each region to arguments
Author: Andrew Litteken Date: 2020-12-23T13:03:05-06:00 New Revision: b1191c843804c2b2b98ebc88a890589ab7f9af23 URL: https://github.com/llvm/llvm-project/commit/b1191c843804c2b2b98ebc88a890589ab7f9af23 DIFF: https://github.com/llvm/llvm-project/commit/b1191c843804c2b2b98ebc88a890589ab7f9af23.diff LOG: [IROutliner] Adding support for elevating constants that are not the same in each region to arguments When there are constants that have the same structural location, but not the same value, between different regions, we cannot simply outline the region. Instead, we find the constants that are not the same in each location, and promote them to arguments to be passed into the respective functions. At each call site, we pass the constant in as an argument regardless of type. Added/Edited Tests: llvm/test/Transforms/IROutliner/outlining-constants-vs-registers.ll llvm/test/Transforms/IROutliner/outlining-different-constants.ll llvm/test/Transforms/IROutliner/outlining-different-globals.ll Reviewers: paquette, jroelofs Differential Revision: https://reviews.llvm.org/D87294 Added: Modified: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/outlining-constants-vs-registers.ll llvm/test/Transforms/IROutliner/outlining-different-constants.ll llvm/test/Transforms/IROutliner/outlining-different-globals.ll Removed: diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h index 01f870097972..87f276d82df7 100644 --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -81,6 +81,12 @@ struct OutlinableRegion { DenseMap ExtractedArgToAgg; DenseMap AggArgToExtracted; + /// Mapping of the argument number in the deduplicated function + /// to a given constant, which is used when creating the arguments to the call + /// to the newly created deduplicated function. This is handled separately + /// since the CodeExtractor does not recognize constants. + DenseMap AggArgToConstant; + /// Used to create an outlined function. CodeExtractor *CE = nullptr; @@ -180,8 +186,11 @@ class IROutliner { /// function if needed. /// /// \param [in] M - The module to outline from. - /// \param [in,out] Region - The region to be extracted - void findAddInputsOutputs(Module &M, OutlinableRegion &Region); + /// \param [in,out] Region - The region to be extracted. + /// \param [in] NotSame - The global value numbers of the Values in the region + /// that do not have the same Constant in each strucutrally similar region. + void findAddInputsOutputs(Module &M, OutlinableRegion &Region, +DenseSet &NotSame); /// Extract \p Region into its own function. /// diff --git a/llvm/lib/Transforms/IPO/IROutliner.cpp b/llvm/lib/Transforms/IPO/IROutliner.cpp index c879031faf5a..5b19d0718ab6 100644 --- a/llvm/lib/Transforms/IPO/IROutliner.cpp +++ b/llvm/lib/Transforms/IPO/IROutliner.cpp @@ -211,6 +211,8 @@ static bool collectRegionsConstants(OutlinableRegion &Region, DenseMap &GVNToConstant, DenseSet &NotSame) { + bool ConstantsTheSame = true; + IRSimilarityCandidate &C = *Region.Candidate; for (IRInstructionData &ID : C) { @@ -222,11 +224,10 @@ collectRegionsConstants(OutlinableRegion &Region, assert(GVNOpt.hasValue() && "Expected a GVN for operand?"); unsigned GVN = GVNOpt.getValue(); - // If this global value has been found to not be the same, it could have - // just been a register, check that it is not a constant value. + // Check if this global value has been found to not be the same already. if (NotSame.find(GVN) != NotSame.end()) { if (isa(V)) - return false; + ConstantsTheSame = false; continue; } @@ -239,30 +240,27 @@ collectRegionsConstants(OutlinableRegion &Region, if (ConstantMatches.getValue()) continue; else - return false; + ConstantsTheSame = false; } // While this value is a register, it might not have been previously, // make sure we don't already have a constant mapped to this global value // number. if (GVNToConstant.find(GVN) != GVNToConstant.end()) -return false; +ConstantsTheSame = false; NotSame.insert(GVN); } } - return true; + return ConstantsTheSame; } void OutlinableGroup::findSameConstants(DenseSet &NotSame) { DenseMap GVNToConstant; for (OutlinableRegion *Region : Regions) -if (!collectRegionsConstants(*Region, GVNToConstant, NotSame)) { - IgnoreGroup = true; - return; -} +collectRegionsConstants(*Region, GVNToConstant, NotSame); } Function *IROutliner::createFunction(Modu
[llvm-branch-commits] [llvm] cce473e - [IRSim] Adding commutativity matching to structure checking
Author: Andrew Litteken Date: 2020-12-23T15:02:00-06:00 New Revision: cce473e0c56408237ea9ac5e24df918afab91ec9 URL: https://github.com/llvm/llvm-project/commit/cce473e0c56408237ea9ac5e24df918afab91ec9 DIFF: https://github.com/llvm/llvm-project/commit/cce473e0c56408237ea9ac5e24df918afab91ec9.diff LOG: [IRSim] Adding commutativity matching to structure checking Certain instructions, such as adds and multiplies can have the operands flipped and still be considered the same. When we are analyzing structure, this gives slightly more flexibility to create a mapping from one region to another. We can add both operands in a corresponding instruction to an operand rather than just the exact match. We then try to eliminate items from the set, until there is only one valid mapping between the regions of code. We do this for adds, multiplies, and equality checking. However, this is not done for floating point instructions, since the order can still matter in some cases. Tests: llvm/test/Transforms/IROutliner/outlining-commutative-fp.ll llvm/test/Transforms/IROutliner/outlining-commutative.ll llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87311 Added: llvm/test/Transforms/IROutliner/outlining-commutative-fp.ll llvm/test/Transforms/IROutliner/outlining-commutative.ll Modified: llvm/include/llvm/Analysis/IRSimilarityIdentifier.h llvm/lib/Analysis/IRSimilarityIdentifier.cpp llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp Removed: diff --git a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h index 30f32492937a..4bc5a17b57e5 100644 --- a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h +++ b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h @@ -504,7 +504,20 @@ class IRSimilarityCandidate { /// \param B - The second IRInstructionCandidate, operand values, and current /// operand mappings to compare. /// \returns true if the IRSimilarityCandidates operands are compatible. - static bool compareOperandMapping(OperandMapping A, OperandMapping B); + static bool compareNonCommutativeOperandMapping(OperandMapping A, + OperandMapping B); + + /// Compare the operands in \p A and \p B and check that the current mapping + /// of global value numbers from \p A to \p B and \p B to \A is consistent + /// given that the operands are commutative. + /// + /// \param A - The first IRInstructionCandidate, operand values, and current + /// operand mappings to compare. + /// \param B - The second IRInstructionCandidate, operand values, and current + /// operand mappings to compare. + /// \returns true if the IRSimilarityCandidates operands are compatible. + static bool compareCommutativeOperandMapping(OperandMapping A, + OperandMapping B); /// Compare the start and end indices of the two IRSimilarityCandidates for /// whether they overlap. If the start instruction of one diff --git a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp index 41e234651349..28b0382bba36 100644 --- a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp +++ b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp @@ -15,6 +15,7 @@ #include "llvm/Analysis/IRSimilarityIdentifier.h" #include "llvm/ADT/DenseMap.h" #include "llvm/IR/Intrinsics.h" +#include "llvm/IR/Operator.h" #include "llvm/IR/User.h" #include "llvm/InitializePasses.h" #include "llvm/Support/SuffixTree.h" @@ -241,6 +242,96 @@ bool IRSimilarityCandidate::isSimilar(const IRSimilarityCandidate &A, }); } +/// Determine if one or more of the assigned global value numbers for the +/// operands in \p TargetValueNumbers is in the current mapping set for operand +/// numbers in \p SourceOperands. The set of possible corresponding global +/// value numbers are replaced with the most recent version of compatible +/// values. +/// +/// \param [in] SourceValueToNumberMapping - The mapping of a Value to global +/// value number for the source IRInstructionCandidate. +/// \param [in, out] CurrentSrcTgtNumberMapping - The current mapping of source +/// IRSimilarityCandidate global value numbers to a set of possible numbers in +/// the target. +/// \param [in] SourceOperands - The operands in the original +/// IRSimilarityCandidate in the current instruction. +/// \param [in] TargetValueNumbers - The global value numbers of the operands in +/// the corresponding Instruction in the other IRSimilarityCandidate. +/// \returns true if there exists a possible mapping between the source +/// Instruction operands and the target Instruction operands, and false if not. +static bool checkNumberingAndReplaceCommutative( + const DenseMap &SourceValueToNumberMapping, + DenseMap>
[llvm-branch-commits] [llvm] 0503926 - [IRSim] Adding support for isomorphic predicates
Author: Andrew Litteken Date: 2020-12-23T15:02:00-06:00 New Revision: 050392660249c70c00e909ae4a7151ba2c766235 URL: https://github.com/llvm/llvm-project/commit/050392660249c70c00e909ae4a7151ba2c766235 DIFF: https://github.com/llvm/llvm-project/commit/050392660249c70c00e909ae4a7151ba2c766235.diff LOG: [IRSim] Adding support for isomorphic predicates Some predicates, can be considered the same as long as the operands are flipped. For example, a > b gives the same result as b > a. This maps instructions in a greater than form, to their appropriate less than form, swapping the operands in the IRInstructionData only, allowing for more flexible matching. Tests: llvm/test/Transforms/IROutliner/outlining-isomorphic-predicates.ll llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp Reviewers: jroelofs, paquette Differential Revision: https://reviews.llvm.org/D87310 Added: llvm/test/Transforms/IROutliner/outlining-isomorphic-predicates.ll Modified: llvm/include/llvm/Analysis/IRSimilarityIdentifier.h llvm/lib/Analysis/IRSimilarityIdentifier.cpp llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp Removed: diff --git a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h index 4bc5a17b57e5..99a5fcb3a578 100644 --- a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h +++ b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h @@ -122,6 +122,11 @@ struct IRInstructionData : ilist_node { /// considered similar. bool Legal; + /// This is only relevant if we are wrapping a CmpInst where we needed to + /// change the predicate of a compare instruction from a greater than form + /// to a less than form. It is None otherwise. + Optional RevisedPredicate; + /// Gather the information that is diff icult to gather for an Instruction, or /// is changed. i.e. the operands of an Instruction and the Types of those /// operands. This extra information allows for similarity matching to make @@ -129,6 +134,17 @@ struct IRInstructionData : ilist_node { /// Instruction performs the same operation. IRInstructionData(Instruction &I, bool Legality, IRInstructionDataList &IDL); + /// Get the predicate that the compare instruction is using for hashing the + /// instruction. the IRInstructionData must be wrapping a CmpInst. + CmpInst::Predicate getPredicate() const; + + /// A function that swaps the predicates to their less than form if they are + /// in a greater than form. Otherwise, the predicate is unchanged. + /// + /// \param CI - The comparison operation to find a consistent preidcate for. + /// \return the consistent comparison predicate. + static CmpInst::Predicate predicateForConsistency(CmpInst *CI); + /// Hashes \p Value based on its opcode, types, and operand types. /// Two IRInstructionData instances produce the same hash when they perform /// the same operation. @@ -161,6 +177,12 @@ struct IRInstructionData : ilist_node { for (Value *V : ID.OperVals) OperTypes.push_back(V->getType()); +if (isa(ID.Inst)) + return llvm::hash_combine( + llvm::hash_value(ID.Inst->getOpcode()), + llvm::hash_value(ID.Inst->getType()), + llvm::hash_value(ID.getPredicate()), + llvm::hash_combine_range(OperTypes.begin(), OperTypes.end())); return llvm::hash_combine( llvm::hash_value(ID.Inst->getOpcode()), llvm::hash_value(ID.Inst->getType()), diff --git a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp index 28b0382bba36..4ee152450c05 100644 --- a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp +++ b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp @@ -26,15 +26,84 @@ using namespace IRSimilarity; IRInstructionData::IRInstructionData(Instruction &I, bool Legality, IRInstructionDataList &IDList) : Inst(&I), Legal(Legality), IDL(&IDList) { - // Here we collect the operands to be used to determine whether two - // instructions are similar to one another. - for (Use &OI : I.operands()) + // We check for whether we have a comparison instruction. If it is, we + // find the "less than" version of the predicate for consistency for + // comparison instructions throught the program. + if (CmpInst *C = dyn_cast(&I)) { +CmpInst::Predicate Predicate = predicateForConsistency(C); +if (Predicate != C->getPredicate()) + RevisedPredicate = Predicate; + } + + // Here we collect the operands and their types for determining whether + // the structure of the operand use matches between two diff erent candidates. + for (Use &OI : I.operands()) { +if (isa(I) && RevisedPredicate.hasValue()) { + // If we have a CmpInst where the predicate is reversed, it means the + // operands must be reversed as well. + OperVals.insert(OperVals.begin(), OI.get())
[llvm-branch-commits] [llvm] 45a4f34 - Revert "[IRSim] Adding support for isomorphic predicates"
Author: Andrew Litteken Date: 2020-12-23T15:14:19-06:00 New Revision: 45a4f34bd194acdfe3472406c303a97dc4e2526f URL: https://github.com/llvm/llvm-project/commit/45a4f34bd194acdfe3472406c303a97dc4e2526f DIFF: https://github.com/llvm/llvm-project/commit/45a4f34bd194acdfe3472406c303a97dc4e2526f.diff LOG: Revert "[IRSim] Adding support for isomorphic predicates" Reverting due to unit test errors between commits. This reverts commit 050392660249c70c00e909ae4a7151ba2c766235. Added: Modified: llvm/include/llvm/Analysis/IRSimilarityIdentifier.h llvm/lib/Analysis/IRSimilarityIdentifier.cpp llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp Removed: llvm/test/Transforms/IROutliner/outlining-isomorphic-predicates.ll diff --git a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h index 99a5fcb3a578..4bc5a17b57e5 100644 --- a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h +++ b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h @@ -122,11 +122,6 @@ struct IRInstructionData : ilist_node { /// considered similar. bool Legal; - /// This is only relevant if we are wrapping a CmpInst where we needed to - /// change the predicate of a compare instruction from a greater than form - /// to a less than form. It is None otherwise. - Optional RevisedPredicate; - /// Gather the information that is diff icult to gather for an Instruction, or /// is changed. i.e. the operands of an Instruction and the Types of those /// operands. This extra information allows for similarity matching to make @@ -134,17 +129,6 @@ struct IRInstructionData : ilist_node { /// Instruction performs the same operation. IRInstructionData(Instruction &I, bool Legality, IRInstructionDataList &IDL); - /// Get the predicate that the compare instruction is using for hashing the - /// instruction. the IRInstructionData must be wrapping a CmpInst. - CmpInst::Predicate getPredicate() const; - - /// A function that swaps the predicates to their less than form if they are - /// in a greater than form. Otherwise, the predicate is unchanged. - /// - /// \param CI - The comparison operation to find a consistent preidcate for. - /// \return the consistent comparison predicate. - static CmpInst::Predicate predicateForConsistency(CmpInst *CI); - /// Hashes \p Value based on its opcode, types, and operand types. /// Two IRInstructionData instances produce the same hash when they perform /// the same operation. @@ -177,12 +161,6 @@ struct IRInstructionData : ilist_node { for (Value *V : ID.OperVals) OperTypes.push_back(V->getType()); -if (isa(ID.Inst)) - return llvm::hash_combine( - llvm::hash_value(ID.Inst->getOpcode()), - llvm::hash_value(ID.Inst->getType()), - llvm::hash_value(ID.getPredicate()), - llvm::hash_combine_range(OperTypes.begin(), OperTypes.end())); return llvm::hash_combine( llvm::hash_value(ID.Inst->getOpcode()), llvm::hash_value(ID.Inst->getType()), diff --git a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp index 4ee152450c05..28b0382bba36 100644 --- a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp +++ b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp @@ -26,84 +26,15 @@ using namespace IRSimilarity; IRInstructionData::IRInstructionData(Instruction &I, bool Legality, IRInstructionDataList &IDList) : Inst(&I), Legal(Legality), IDL(&IDList) { - // We check for whether we have a comparison instruction. If it is, we - // find the "less than" version of the predicate for consistency for - // comparison instructions throught the program. - if (CmpInst *C = dyn_cast(&I)) { -CmpInst::Predicate Predicate = predicateForConsistency(C); -if (Predicate != C->getPredicate()) - RevisedPredicate = Predicate; - } - - // Here we collect the operands and their types for determining whether - // the structure of the operand use matches between two diff erent candidates. - for (Use &OI : I.operands()) { -if (isa(I) && RevisedPredicate.hasValue()) { - // If we have a CmpInst where the predicate is reversed, it means the - // operands must be reversed as well. - OperVals.insert(OperVals.begin(), OI.get()); - continue; -} - + // Here we collect the operands to be used to determine whether two + // instructions are similar to one another. + for (Use &OI : I.operands()) OperVals.push_back(OI.get()); - } -} - -CmpInst::Predicate IRInstructionData::predicateForConsistency(CmpInst *CI) { - switch (CI->getPredicate()) { - case CmpInst::FCMP_OGT: - case CmpInst::FCMP_UGT: - case CmpInst::FCMP_OGE: - case CmpInst::FCMP_UGE: - case CmpInst::ICMP_SGT: - case CmpInst::ICMP_UGT: - case CmpInst::ICMP_SGE: - case CmpInst::ICMP_UGE: -
[llvm-branch-commits] [llvm] 48ad819 - [IRSim] Adding support for isomorphic predicates
Author: Andrew Litteken Date: 2020-12-23T19:42:35-06:00 New Revision: 48ad8194a56f350e84383fff7cb705820ea850bc URL: https://github.com/llvm/llvm-project/commit/48ad8194a56f350e84383fff7cb705820ea850bc DIFF: https://github.com/llvm/llvm-project/commit/48ad8194a56f350e84383fff7cb705820ea850bc.diff LOG: [IRSim] Adding support for isomorphic predicates Some predicates, can be considered the same as long as the operands are flipped. For example, a > b gives the same result as b > a. This maps instructions in a greater than form, to their appropriate less than form, swapping the operands in the IRInstructionData only, allowing for more flexible matching. Tests: llvm/test/Transforms/IROutliner/outlining-isomorphic-predicates.ll llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp Reviewers: jroelofs, paquette Recommit of commit 050392660249c70c00e909ae4a7151ba2c766235 Differential Revision: https://reviews.llvm.org/D87310 Added: llvm/test/Transforms/IROutliner/outlining-isomorphic-predicates.ll Modified: llvm/include/llvm/Analysis/IRSimilarityIdentifier.h llvm/lib/Analysis/IRSimilarityIdentifier.cpp llvm/unittests/Analysis/IRSimilarityIdentifierTest.cpp Removed: diff --git a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h index 4bc5a17b57e5..99a5fcb3a578 100644 --- a/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h +++ b/llvm/include/llvm/Analysis/IRSimilarityIdentifier.h @@ -122,6 +122,11 @@ struct IRInstructionData : ilist_node { /// considered similar. bool Legal; + /// This is only relevant if we are wrapping a CmpInst where we needed to + /// change the predicate of a compare instruction from a greater than form + /// to a less than form. It is None otherwise. + Optional RevisedPredicate; + /// Gather the information that is diff icult to gather for an Instruction, or /// is changed. i.e. the operands of an Instruction and the Types of those /// operands. This extra information allows for similarity matching to make @@ -129,6 +134,17 @@ struct IRInstructionData : ilist_node { /// Instruction performs the same operation. IRInstructionData(Instruction &I, bool Legality, IRInstructionDataList &IDL); + /// Get the predicate that the compare instruction is using for hashing the + /// instruction. the IRInstructionData must be wrapping a CmpInst. + CmpInst::Predicate getPredicate() const; + + /// A function that swaps the predicates to their less than form if they are + /// in a greater than form. Otherwise, the predicate is unchanged. + /// + /// \param CI - The comparison operation to find a consistent preidcate for. + /// \return the consistent comparison predicate. + static CmpInst::Predicate predicateForConsistency(CmpInst *CI); + /// Hashes \p Value based on its opcode, types, and operand types. /// Two IRInstructionData instances produce the same hash when they perform /// the same operation. @@ -161,6 +177,12 @@ struct IRInstructionData : ilist_node { for (Value *V : ID.OperVals) OperTypes.push_back(V->getType()); +if (isa(ID.Inst)) + return llvm::hash_combine( + llvm::hash_value(ID.Inst->getOpcode()), + llvm::hash_value(ID.Inst->getType()), + llvm::hash_value(ID.getPredicate()), + llvm::hash_combine_range(OperTypes.begin(), OperTypes.end())); return llvm::hash_combine( llvm::hash_value(ID.Inst->getOpcode()), llvm::hash_value(ID.Inst->getType()), diff --git a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp index 28b0382bba36..4ee152450c05 100644 --- a/llvm/lib/Analysis/IRSimilarityIdentifier.cpp +++ b/llvm/lib/Analysis/IRSimilarityIdentifier.cpp @@ -26,15 +26,84 @@ using namespace IRSimilarity; IRInstructionData::IRInstructionData(Instruction &I, bool Legality, IRInstructionDataList &IDList) : Inst(&I), Legal(Legality), IDL(&IDList) { - // Here we collect the operands to be used to determine whether two - // instructions are similar to one another. - for (Use &OI : I.operands()) + // We check for whether we have a comparison instruction. If it is, we + // find the "less than" version of the predicate for consistency for + // comparison instructions throught the program. + if (CmpInst *C = dyn_cast(&I)) { +CmpInst::Predicate Predicate = predicateForConsistency(C); +if (Predicate != C->getPredicate()) + RevisedPredicate = Predicate; + } + + // Here we collect the operands and their types for determining whether + // the structure of the operand use matches between two diff erent candidates. + for (Use &OI : I.operands()) { +if (isa(I) && RevisedPredicate.hasValue()) { + // If we have a CmpInst where the predicate is reversed, it means the + // operands must be reverse
[llvm-branch-commits] [llvm] bf899e8 - [IRSim][IROutliner] Adding the extraction basics for the IROutliner.
Author: Andrew Litteken Date: 2020-11-27T19:08:29-06:00 New Revision: bf899e891387d07dfd12de195ce2a16f62afd5e0 URL: https://github.com/llvm/llvm-project/commit/bf899e891387d07dfd12de195ce2a16f62afd5e0 DIFF: https://github.com/llvm/llvm-project/commit/bf899e891387d07dfd12de195ce2a16f62afd5e0.diff LOG: [IRSim][IROutliner] Adding the extraction basics for the IROutliner. Extracting the similar regions is the first step in the IROutliner. Using the IRSimilarityIdentifier, we collect the SimilarityGroups and sort them by how many instructions will be removed. Each IRSimilarityCandidate is used to define an OutlinableRegion. Each region is ordered by their occurrence in the Module and the regions that are not compatible with previously outlined regions are discarded. Each region is then extracted with the CodeExtractor into its own function. We test that correctly extract in: test/Transforms/IROutliner/extraction.ll test/Transforms/IROutliner/address-taken.ll test/Transforms/IROutliner/outlining-same-globals.ll test/Transforms/IROutliner/outlining-same-constants.ll test/Transforms/IROutliner/outlining-different-structure.ll Reviewers: paquette, jroelofs, yroux Differential Revision: https://reviews.llvm.org/D86975 Added: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/outlining-address-taken.ll llvm/test/Transforms/IROutliner/outlining-different-structure.ll llvm/test/Transforms/IROutliner/outlining-same-constants.ll llvm/test/Transforms/IROutliner/outlining-same-globals.ll Modified: llvm/include/llvm/InitializePasses.h llvm/include/llvm/Transforms/IPO.h llvm/lib/Passes/PassBuilder.cpp llvm/lib/Passes/PassRegistry.def llvm/lib/Transforms/IPO/CMakeLists.txt llvm/lib/Transforms/IPO/IPO.cpp llvm/lib/Transforms/IPO/PassManagerBuilder.cpp Removed: diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 0d0eaf0bca83..0ec87fb09e49 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -183,6 +183,7 @@ void initializeHotColdSplittingLegacyPassPass(PassRegistry&); void initializeHWAddressSanitizerLegacyPassPass(PassRegistry &); void initializeIPSCCPLegacyPassPass(PassRegistry&); void initializeIRCELegacyPassPass(PassRegistry&); +void initializeIROutlinerLegacyPassPass(PassRegistry&); void initializeIRSimilarityIdentifierWrapperPassPass(PassRegistry&); void initializeIRTranslatorPass(PassRegistry&); void initializeIVUsersWrapperPassPass(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/IPO.h b/llvm/include/llvm/Transforms/IPO.h index 1918ad76a270..af357181597a 100644 --- a/llvm/include/llvm/Transforms/IPO.h +++ b/llvm/include/llvm/Transforms/IPO.h @@ -215,6 +215,11 @@ ModulePass *createMergeFunctionsPass(); /// function(s). ModulePass *createHotColdSplittingPass(); +//===--===// +/// createIROutlinerPass - This pass finds similar code regions and factors +/// those regions out into functions. +ModulePass *createIROutlinerPass(); + //===--===// /// createPartialInliningPass - This pass inlines parts of functions. /// diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h new file mode 100644 index ..dd169602f004 --- /dev/null +++ b/llvm/include/llvm/Transforms/IPO/IROutliner.h @@ -0,0 +1,186 @@ +//===- IROutliner.h - Extract similar IR regions into functions ==// +// +// 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 +// +//===--===// +// +// \file +// The interface file for the IROutliner which is used by the IROutliner Pass. +// +// The outliner uses the IRSimilarityIdentifier to identify the similar regions +// of code. It evaluates each set of IRSimilarityCandidates with an estimate of +// whether it will provide code size reduction. Each region is extracted using +// the code extractor. These extracted functions are consolidated into a single +// function and called from the extracted call site. +// +// For example: +// \code +// %1 = add i32 %a, %b +// %2 = add i32 %b, %a +// %3 = add i32 %b, %a +// %4 = add i32 %a, %b +// \endcode +// would become function +// \code +// define internal void outlined_ir_function(i32 %0, i32 %1) { +// %1 = add i32 %0, %1 +// %2 = add i32 %1, %0 +// ret void +// } +// \endcode +// with calls: +// \code +// call void outlined_ir_function(i32 %a, i32 %b) +//
[llvm-branch-commits] [llvm] a8a43b6 - Revert "[IRSim][IROutliner] Adding the extraction basics for the IROutliner."
Author: Andrew Litteken Date: 2020-11-27T19:55:57-06:00 New Revision: a8a43b63388f4d348eaa1f1017d6ab3be89b4945 URL: https://github.com/llvm/llvm-project/commit/a8a43b63388f4d348eaa1f1017d6ab3be89b4945 DIFF: https://github.com/llvm/llvm-project/commit/a8a43b63388f4d348eaa1f1017d6ab3be89b4945.diff LOG: Revert "[IRSim][IROutliner] Adding the extraction basics for the IROutliner." Reverting commit due to address sanitizer errors. > Extracting the similar regions is the first step in the IROutliner. > > Using the IRSimilarityIdentifier, we collect the SimilarityGroups and > sort them by how many instructions will be removed. Each > IRSimilarityCandidate is used to define an OutlinableRegion. Each > region is ordered by their occurrence in the Module and the regions that > are not compatible with previously outlined regions are discarded. > > Each region is then extracted with the CodeExtractor into its own > function. > > We test that correctly extract in: > test/Transforms/IROutliner/extraction.ll > test/Transforms/IROutliner/address-taken.ll > test/Transforms/IROutliner/outlining-same-globals.ll > test/Transforms/IROutliner/outlining-same-constants.ll > test/Transforms/IROutliner/outlining-different-structure.ll > > Reviewers: paquette, jroelofs, yroux > > Differential Revision: https://reviews.llvm.org/D86975 This reverts commit bf899e891387d07dfd12de195ce2a16f62afd5e0. Added: Modified: llvm/include/llvm/InitializePasses.h llvm/include/llvm/Transforms/IPO.h llvm/lib/Passes/PassBuilder.cpp llvm/lib/Passes/PassRegistry.def llvm/lib/Transforms/IPO/CMakeLists.txt llvm/lib/Transforms/IPO/IPO.cpp llvm/lib/Transforms/IPO/PassManagerBuilder.cpp Removed: llvm/include/llvm/Transforms/IPO/IROutliner.h llvm/lib/Transforms/IPO/IROutliner.cpp llvm/test/Transforms/IROutliner/extraction.ll llvm/test/Transforms/IROutliner/outlining-address-taken.ll llvm/test/Transforms/IROutliner/outlining-different-structure.ll llvm/test/Transforms/IROutliner/outlining-same-constants.ll llvm/test/Transforms/IROutliner/outlining-same-globals.ll diff --git a/llvm/include/llvm/InitializePasses.h b/llvm/include/llvm/InitializePasses.h index 0ec87fb09e49..0d0eaf0bca83 100644 --- a/llvm/include/llvm/InitializePasses.h +++ b/llvm/include/llvm/InitializePasses.h @@ -183,7 +183,6 @@ void initializeHotColdSplittingLegacyPassPass(PassRegistry&); void initializeHWAddressSanitizerLegacyPassPass(PassRegistry &); void initializeIPSCCPLegacyPassPass(PassRegistry&); void initializeIRCELegacyPassPass(PassRegistry&); -void initializeIROutlinerLegacyPassPass(PassRegistry&); void initializeIRSimilarityIdentifierWrapperPassPass(PassRegistry&); void initializeIRTranslatorPass(PassRegistry&); void initializeIVUsersWrapperPassPass(PassRegistry&); diff --git a/llvm/include/llvm/Transforms/IPO.h b/llvm/include/llvm/Transforms/IPO.h index af357181597a..1918ad76a270 100644 --- a/llvm/include/llvm/Transforms/IPO.h +++ b/llvm/include/llvm/Transforms/IPO.h @@ -215,11 +215,6 @@ ModulePass *createMergeFunctionsPass(); /// function(s). ModulePass *createHotColdSplittingPass(); -//===--===// -/// createIROutlinerPass - This pass finds similar code regions and factors -/// those regions out into functions. -ModulePass *createIROutlinerPass(); - //===--===// /// createPartialInliningPass - This pass inlines parts of functions. /// diff --git a/llvm/include/llvm/Transforms/IPO/IROutliner.h b/llvm/include/llvm/Transforms/IPO/IROutliner.h deleted file mode 100644 index dd169602f004.. --- a/llvm/include/llvm/Transforms/IPO/IROutliner.h +++ /dev/null @@ -1,186 +0,0 @@ -//===- IROutliner.h - Extract similar IR regions into functions ==// -// -// 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 -// -//===--===// -// -// \file -// The interface file for the IROutliner which is used by the IROutliner Pass. -// -// The outliner uses the IRSimilarityIdentifier to identify the similar regions -// of code. It evaluates each set of IRSimilarityCandidates with an estimate of -// whether it will provide code size reduction. Each region is extracted using -// the code extractor. These extracted functions are consolidated into a single -// function and called from the extracted call site. -// -// For example: -// \code -// %1 = add i32 %a, %b -// %2 = add i32 %b, %a -// %3 = add i32 %b, %a -// %4 = add i32 %a, %b -// \endcode -// would become function -// \code -// define internal void outlined_ir_function(i32 %0, i32 %1) {