[llvm] r311038 - [MachineCopyPropagation] Extend pass to do COPY source forwarding
Vitaly Buka via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 23 14:54:02 PDT 2017
How long do you wait? it's OK if not output for a few minutes.
On Tue, Aug 22, 2017 at 8:46 PM, Geoff Berry <gberry at codeaurora.org> wrote:
> I've been trying to reproduce this failure, but I'm getting check-asan
> hangs even if I test the revision with my latest revert:
>
> Is there something I need to do to the device that isn't done by these
> scripts? Are there additional environment variables I need to set before
> running?
>
> For the record I'm running:
> $ BUILDBOT_CLOBBER= BUILDBOT_REVISION=311142 ./buildbot_android.sh
>
> r311142 is my latest reversion of my MachineCopyPropagation changes
> and the only changes I've made to the scripts are:
> - change the svn repo to be https:// instead of http:// to avoid svn
> timeouts
> - add -DLLVM_LIT_ARGS="-v" to the compiler-rt cmake args so running
> check-asan will print the tests names as they run to the log file
>
> It appears that the following tests are hanging:
> /data/local/tmp/Output/deep_call_stack.cc.tmp
> /data/local/tmp/Output/interception_test.cc.tmp
> /data/local/tmp/Output/quarantine_size_mb.cc.tmp
> /data/local/tmp/Output/thread_local_quarantine_size_kb.cc.tmp
> /data/local/tmp/Output/coverage-module-unloaded.cc.tmp.exe
> /data/local/tmp/Output/coverage-reset.cc.tmp
> /data/local/tmp/Output/coverage.cc.tmp
> /data/local/tmp/Output/start-deactivated.cc.tmp
>
>
> On 8/17/2017 9:24 PM, Vitaly Buka wrote:
>
>> If you have android with arm 32bit, you probably can reproduce with
>> running https://llvm.org/svn/llvm-project/zorg/trunk/zorg/buildbot/
>> builders/sanitizers/buildbot_android.sh in empty directory.
>>
>> On Thu, Aug 17, 2017 at 6:23 PM, Vitaly Buka <vitalybuka at google.com
>> <mailto:vitalybuka at google.com>> wrote:
>>
>> I just hangs on "Running the AddressSanitizer tests" for arm
>>
>> /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux
>> -android/build/compiler_rt_build_android_arm/lib/asan/tests/AsanTest:
>> 1 file pus
>> hed. 3.7 MB/s (10602792 bytes in 2.742s)
>> + echo @@@BUILD_STEP run asan lit tests
>> '[arm/sailfish-userdebug/OPR1.170621.001]@@@'
>> @@@BUILD_STEP run asan lit tests
>> [arm/sailfish-userdebug/OPR1.170621.001]@@@
>> + cd
>> /var/lib/buildbot/sanitizer-buildbot6/sanitizer-x86_64-linux
>> -android/build/compiler_rt_build_android_arm
>> + ninja check-asan
>> [1/1] Running the AddressSanitizer tests
>>
>>
>> But the same device passes aarch64 tests:
>> [1/1] Running the AddressSanitizer tests
>> -- Testing: 407 tests, 12 threads --
>> Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..
>> Testing Time: 87.09s
>> Expected Passes : 202
>> Expected Failures : 27
>> Unsupported Tests : 178
>> + echo @@@BUILD_STEP run sanitizer_common tests
>> '[aarch64/sailfish-userdebug/OPR1.170621.001]@@@'
>> @@@BUILD_STEP run sanitizer_common tests
>> [aarch64/sailfish-userdebug/OPR1.170621.001]@@@
>>
>>
>>
>> On Thu, Aug 17, 2017 at 5:42 PM, Geoff Berry <gberry at codeaurora.org
>> <mailto:gberry at codeaurora.org>> wrote:
>>
>> It seems like this is still happening after fixing a couple of
>> issues with this patch. I'll revert again shortly. I'm having
>> a hard time understanding what is failing from looking at the
>> buildbot logs though. Do you have any way of determining what
>> exactly is timing out?
>>
>> On 8/16/2017 11:13 PM, Vitaly Buka wrote:
>>
>> Looks like after this patch Android tests consistently hang
>> http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-
>> android/builds/1825
>> <http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-
>> android/builds/1825>
>>
>> On Wed, Aug 16, 2017 at 1:50 PM, Geoff Berry via
>> llvm-commits <llvm-commits at lists.llvm.org
>> <mailto:llvm-commits at lists.llvm.org>
>> <mailto:llvm-commits at lists.llvm.org
>> <mailto:llvm-commits at lists.llvm.org>>> wrote:
>>
>> Author: gberry
>> Date: Wed Aug 16 13:50:01 2017
>> New Revision: 311038
>>
>> URL:
>> http://llvm.org/viewvc/llvm-project?rev=311038&view=rev
>> <http://llvm.org/viewvc/llvm-project?rev=311038&view=rev>
>> <http://llvm.org/viewvc/llvm-p
>> roject?rev=311038&view=rev
>> <http://llvm.org/viewvc/llvm-project?rev=311038&view=rev>>
>> Log:
>> [MachineCopyPropagation] Extend pass to do COPY source
>> forwarding
>>
>> This change extends MachineCopyPropagation to do COPY
>> source forwarding.
>>
>> This change also extends the MachineCopyPropagation
>> pass to be able to
>> be run during register allocation, after physical
>> registers have been
>> assigned, but before the virtual registers have been
>> re-written, which
>> allows it to remove virtual register COPY LiveIntervals
>> that become dead
>> through the forwarding of all of their uses.
>>
>> Reviewers: qcolombet, javed.absar, MatzeB, jonpa
>>
>> Subscribers: jyknight, nemanjai, llvm-commits,
>> nhaehnle, mcrosier,
>> mgorny
>>
>> Differential Revision: https://reviews.llvm.org/D30751
>> <https://reviews.llvm.org/D30751>
>> <https://reviews.llvm.org/D30751
>> <https://reviews.llvm.org/D30751>>
>>
>> Modified:
>> llvm/trunk/include/llvm/CodeGen/Passes.h
>> llvm/trunk/include/llvm/InitializePasses.h
>> llvm/trunk/lib/CodeGen/CodeGen.cpp
>> llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp
>> llvm/trunk/lib/CodeGen/TargetPassConfig.cpp
>> llvm/trunk/test/CodeGen/AArc
>> h64/aarch64-fold-lslfast.ll
>> llvm/trunk/test/CodeGen/AArc
>> h64/arm64-AdvSIMD-Scalar.ll
>> llvm/trunk/test/CodeGen/AArc
>> h64/arm64-zero-cycle-regmov.ll
>> llvm/trunk/test/CodeGen/AArch64/f16-instructions.ll
>> llvm/trunk/test/CodeGen/AArch64/flags-multiuse.ll
>> llvm/trunk/test/CodeGen/AArc
>> h64/merge-store-dependency.ll
>> llvm/trunk/test/CodeGen/AArch64/neg-imm.ll
>> llvm/trunk/test/CodeGen/AMDGPU/byval-frame-setup.ll
>> llvm/trunk/test/CodeGen/AMDGP
>> U/call-argument-types.ll
>> llvm/trunk/test/CodeGen/AMDG
>> PU/call-preserved-registers.ll
>> llvm/trunk/test/CodeGen/AMDG
>> PU/callee-special-input-sgprs.ll
>> llvm/trunk/test/CodeGen/AMDG
>> PU/callee-special-input-vgprs.ll
>> llvm/trunk/test/CodeGen/AMDGP
>> U/mubuf-offset-private.ll
>> llvm/trunk/test/CodeGen/AMDGPU/multilevel-break.ll
>> llvm/trunk/test/CodeGen/AMDG
>> PU/private-access-no-objects.ll
>> llvm/trunk/test/CodeGen/AMDGPU/ret.ll
>> llvm/trunk/test/CodeGen/ARM/atomic-op.ll
>> llvm/trunk/test/CodeGen/ARM/swifterror.ll
>> llvm/trunk/test/CodeGen/Mips/llvm-ir/sub.ll
>> llvm/trunk/test/CodeGen/PowerPC/fma-mutate.ll
>> llvm/trunk/test/CodeGen/Power
>> PC/inlineasm-i64-reg.ll
>> llvm/trunk/test/CodeGen/PowerPC/tail-dup-layout.ll
>> llvm/trunk/test/CodeGen/SPARC/32abi.ll
>> llvm/trunk/test/CodeGen/SPARC/atomics.ll
>> llvm/trunk/test/CodeGen/Thumb
>> /thumb-shrink-wrapping.ll
>> llvm/trunk/test/CodeGen/X86/
>> 2006-03-01-InstrSchedBug.ll
>> llvm/trunk/test/CodeGen/X86/arg-copy-elide.ll
>> llvm/trunk/test/CodeGen/X86/avg.ll
>> llvm/trunk/test/CodeGen/X86/avx-load-store.ll
>> llvm/trunk/test/CodeGen/X86/avx512-bugfix-25270.ll
>> llvm/trunk/test/CodeGen/X86/avx512-calling-conv.ll
>> llvm/trunk/test/CodeGen/X86/avx512-mask-op.ll
>> llvm/trunk/test/CodeGen/X86/
>> avx512bw-intrinsics-upgrade.ll
>> llvm/trunk/test/CodeGen/X86/
>> bitcast-int-to-vector-bool-sext.ll
>> llvm/trunk/test/CodeGen/X86/
>> bitcast-int-to-vector-bool-zext.ll
>> llvm/trunk/test/CodeGen/X86/buildvec-insertvec.ll
>> llvm/trunk/test/CodeGen/X86/combine-fcopysign.ll
>> llvm/trunk/test/CodeGen/X86/complex-fastmath.ll
>> llvm/trunk/test/CodeGen/X86/divide-by-constant.ll
>> llvm/trunk/test/CodeGen/X86/fmaxnum.ll
>> llvm/trunk/test/CodeGen/X86/fminnum.ll
>> llvm/trunk/test/CodeGen/X86/fp128-i128.ll
>> llvm/trunk/test/CodeGen/X86/haddsub-2.ll
>> llvm/trunk/test/CodeGen/X86/haddsub-undef.ll
>> llvm/trunk/test/CodeGen/X86/half.ll
>> llvm/trunk/test/CodeGen/X86/inline-asm-fpstack.ll
>> llvm/trunk/test/CodeGen/X86/ipra-local-linkage.ll
>> llvm/trunk/test/CodeGen/X86/localescape.ll
>> llvm/trunk/test/CodeGen/X86/mul-i1024.ll
>> llvm/trunk/test/CodeGen/X86/mul-i512.ll
>> llvm/trunk/test/CodeGen/X86/mul128.ll
>> llvm/trunk/test/CodeGen/X86/pmul.ll
>> llvm/trunk/test/CodeGen/X86/powi.ll
>> llvm/trunk/test/CodeGen/X86/pr11334.ll
>> llvm/trunk/test/CodeGen/X86/pr29112.ll
>> llvm/trunk/test/CodeGen/X86/psubus.ll
>> llvm/trunk/test/CodeGen/X86/select.ll
>> llvm/trunk/test/CodeGen/X86/shrink-wrap-chkstk.ll
>> llvm/trunk/test/CodeGen/X86/sqrt-fastmath.ll
>> llvm/trunk/test/CodeGen/X86/sse-scalar-fp-arith.ll
>> llvm/trunk/test/CodeGen/X86/sse1.ll
>> llvm/trunk/test/CodeGen/X86/sse3-avx-addsub-2.ll
>> llvm/trunk/test/CodeGen/X86/statepoint-live-in.ll
>> llvm/trunk/test/CodeGen/X86/s
>> tatepoint-stack-usage.ll
>> llvm/trunk/test/CodeGen/X86/vec_fp_to_int.ll
>> llvm/trunk/test/CodeGen/X86/vec_int_to_fp.ll
>> llvm/trunk/test/CodeGen/X86/vec_minmax_sint.ll
>> llvm/trunk/test/CodeGen/X86/vec_shift4.ll
>> llvm/trunk/test/CodeGen/X86/vector-blend.ll
>> llvm/trunk/test/CodeGen/X86/vector-idiv-sdiv-128.ll
>> llvm/trunk/test/CodeGen/X86/vector-idiv-udiv-128.ll
>> llvm/trunk/test/CodeGen/X86/vector-rotate-128.ll
>> llvm/trunk/test/CodeGen/X86/vector-sext.ll
>> llvm/trunk/test/CodeGen/X86/v
>> ector-shift-ashr-128.ll
>> llvm/trunk/test/CodeGen/X86/v
>> ector-shift-lshr-128.ll
>> llvm/trunk/test/CodeGen/X86/vector-shift-shl-128.ll
>> llvm/trunk/test/CodeGen/X86/
>> vector-shuffle-combining.ll
>> llvm/trunk/test/CodeGen/X86/vector-trunc-math.ll
>> llvm/trunk/test/CodeGen/X86/vector-zext.ll
>> llvm/trunk/test/CodeGen/X86/vselect-minmax.ll
>> llvm/trunk/test/CodeGen/X86/widen_conv-3.ll
>> llvm/trunk/test/CodeGen/X86/widen_conv-4.ll
>> llvm/trunk/test/CodeGen/X86/x
>> 86-shrink-wrap-unwind.ll
>> llvm/trunk/test/CodeGen/X86/x86-shrink-wrapping.ll
>>
>> Modified: llvm/trunk/include/llvm/CodeGen/Passes.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>> CodeGen/Passes.h?rev=311038&r1=311037&r2=311038&view=diff
>> <http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm
>> /CodeGen/Passes.h?rev=311038&r1=311037&r2=311038&view=diff>
>> <http://llvm.org/viewvc/llvm-p
>> roject/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=311038&
>> r1=311037&r2=311038&view=diff
>> <http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm
>> /CodeGen/Passes.h?rev=311038&r1=311037&r2=311038&view=diff>>
>> ==============================
>> ================================================
>> --- llvm/trunk/include/llvm/CodeGen/Passes.h (original)
>> +++ llvm/trunk/include/llvm/CodeGen/Passes.h Wed Aug 16
>> 13:50:01 2017
>> @@ -278,6 +278,11 @@ namespace llvm {
>> /// MachineSinking - This pass performs sinking on
>> machine
>> instructions.
>> extern char &MachineSinkingID;
>>
>> + /// MachineCopyPropagationPreRegRewrite - This pass
>> performs copy
>> propagation
>> + /// on machine instructions after register
>> allocation but before
>> virtual
>> + /// register re-writing..
>> + extern char &MachineCopyPropagationPreRegRewriteID;
>> +
>> /// MachineCopyPropagation - This pass performs
>> copy propagation on
>> /// machine instructions.
>> extern char &MachineCopyPropagationID;
>>
>> Modified: llvm/trunk/include/llvm/InitializePasses.h
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/
>> InitializePasses.h?rev=311038&r1=311037&r2=311038&view=diff
>> <http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm
>> /InitializePasses.h?rev=311038&r1=311037&r2=311038&view=diff>
>> <http://llvm.org/viewvc/llvm-p
>> roject/llvm/trunk/include/llvm/InitializePasses.h?rev=311038
>> &r1=311037&r2=311038&view=diff
>> <http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm
>> /InitializePasses.h?rev=311038&r1=311037&r2=311038&view=diff>>
>> ==============================
>> ================================================
>> --- llvm/trunk/include/llvm/InitializePasses.h
>> (original)
>> +++ llvm/trunk/include/llvm/InitializePasses.h Wed Aug
>> 16 13:50:01 2017
>> @@ -233,6 +233,7 @@ void
>> initializeMachineBranchProbabilityI
>> void initializeMachineCSEPass(PassRegistry&);
>> void initializeMachineCombinerPass(PassRegistry&);
>> void initializeMachineCopyPropagati
>> onPass(PassRegistry&);
>> +void
>> initializeMachineCopyPropagationPreRegRewritePass(PassRegist
>> ry&);
>> void
>> initializeMachineDominanceFrontierPass(PassRegistry&);
>> void initializeMachineDominatorTree
>> Pass(PassRegistry&);
>> void
>> initializeMachineFunctionPrinterPassPass(PassRegistry&);
>>
>> Modified: llvm/trunk/lib/CodeGen/CodeGen.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/
>> CodeGen.cpp?rev=311038&r1=311037&r2=311038&view=diff
>> <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/
>> CodeGen.cpp?rev=311038&r1=311037&r2=311038&view=diff>
>> <http://llvm.org/viewvc/llvm-p
>> roject/llvm/trunk/lib/CodeGen/CodeGen.cpp?rev=311038&r1=
>> 311037&r2=311038&view=diff
>> <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/
>> CodeGen.cpp?rev=311038&r1=311037&r2=311038&view=diff>>
>> ==============================
>> ================================================
>> --- llvm/trunk/lib/CodeGen/CodeGen.cpp (original)
>> +++ llvm/trunk/lib/CodeGen/CodeGen.cpp Wed Aug 16
>> 13:50:01 2017
>> @@ -54,6 +54,7 @@ void llvm::initializeCodeGen(PassRe
>> gistr
>> initializeMachineCSEPass(Registry);
>> initializeMachineCombinerPass(Registry);
>> initializeMachineCopyPropagationPass(Registry);
>> + initializeMachineCopyPropagati
>> onPreRegRewritePass(Registry);
>> initializeMachineDominatorTreePass(Registry);
>> initializeMachineFunctionPrinterPassPass(Registry);
>> initializeMachineLICMPass(Registry);
>>
>> Modified: llvm/trunk/lib/CodeGen/Machine
>> CopyPropagation.cpp
>> URL:
>> http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/M
>> achineCopyPropagation.cpp?rev=311038&r1=311037&r2=311038&view=diff
>> <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/
>> MachineCopyPropagation.cpp?rev=311038&r1=311037&r2=311038&view=diff>
>> <http://llvm.org/viewvc/llvm-p
>> roject/llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp?rev
>> =311038&r1=311037&r2=311038&view=diff
>> <http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/
>> MachineCopyPropagation.cpp?rev=311038&r1=311037&r2=311038&view=diff>>
>> ==============================
>> ================================================
>> --- llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp
>> (original)
>> +++ llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp
>> Wed Aug 16
>> 13:50:01 2017
>> @@ -7,18 +7,62 @@
>> //
>> //===-------------------------
>> ---------------------------------------------===//
>> //
>> -// This is an extremely simple MachineInstr-level copy
>> propagation
>> pass.
>> +// This is a simple MachineInstr-level copy forwarding
>> pass. It
>> may be run at
>> +// two places in the codegen pipeline:
>> +// - After register allocation but before virtual
>> registers have
>> been remapped
>> +// to physical registers.
>> +// - After physical register remapping.
>> +//
>> +// The optimizations done vary slightly based on
>> whether virtual
>> registers are
>> +// still present. In both cases, this pass forwards
>> the source of
>> COPYs to the
>> +// users of their destinations when doing so is
>> legal. For example:
>> +//
>> +// %vreg1 = COPY %vreg0
>> +// ...
>> +// ... = OP %vreg1
>> +//
>> +// If
>> +// - the physical register assigned to %vreg0 has
>> not been
>> clobbered by the
>> +// time of the use of %vreg1
>> +// - the register class constraints are satisfied
>> +// - the COPY def is the only value that reaches OP
>> +// then this pass replaces the above with:
>> +//
>> +// %vreg1 = COPY %vreg0
>> +// ...
>> +// ... = OP %vreg0
>> +//
>> +// and updates the relevant state required by
>> VirtRegMap (e.g.
>> LiveIntervals).
>> +// COPYs whose LiveIntervals become dead as a result
>> of this
>> forwarding (i.e. if
>> +// all uses of %vreg1 are changed to %vreg0) are
>> removed.
>> +//
>> +// When being run with only physical registers, this
>> pass will also
>> remove some
>> +// redundant COPYs. For example:
>> +//
>> +// %R1 = COPY %R0
>> +// ... // No clobber of %R1
>> +// %R0 = COPY %R1 <<< Removed
>> +//
>> +// or
>> +//
>> +// %R1 = COPY %R0
>> +// ... // No clobber of %R0
>> +// %R1 = COPY %R0 <<< Removed
>> //
>> //===-------------------------
>> ---------------------------------------------===//
>>
>> +#include "LiveDebugVariables.h"
>> #include "llvm/ADT/DenseMap.h"
>> #include "llvm/ADT/SetVector.h"
>> #include "llvm/ADT/SmallVector.h"
>> #include "llvm/ADT/Statistic.h"
>> +#include "llvm/CodeGen/LiveRangeEdit.h"
>> +#include "llvm/CodeGen/LiveStackAnalysis.h"
>> #include "llvm/CodeGen/MachineFunction.h"
>> #include "llvm/CodeGen/MachineFunctionPass.h"
>> #include "llvm/CodeGen/MachineRegisterInfo.h"
>> #include "llvm/CodeGen/Passes.h"
>> +#include "llvm/CodeGen/VirtRegMap.h"
>> #include "llvm/Pass.h"
>> #include "llvm/Support/Debug.h"
>> #include "llvm/Support/raw_ostream.h"
>> @@ -30,24 +74,48 @@ using namespace llvm;
>> #define DEBUG_TYPE "machine-cp"
>>
>> STATISTIC(NumDeletes, "Number of dead copies deleted");
>> +STATISTIC(NumCopyForwards, "Number of copy uses
>> forwarded");
>>
>> namespace {
>> typedef SmallVector<unsigned, 4> RegList;
>> typedef DenseMap<unsigned, RegList> SourceMap;
>> typedef DenseMap<unsigned, MachineInstr*> Reg2MIMap;
>>
>> - class MachineCopyPropagation : public
>> MachineFunctionPass {
>> + class MachineCopyPropagation : public
>> MachineFunctionPass,
>> + private
>> LiveRangeEdit::Delegate {
>> const TargetRegisterInfo *TRI;
>> const TargetInstrInfo *TII;
>> - const MachineRegisterInfo *MRI;
>> + MachineRegisterInfo *MRI;
>> + MachineFunction *MF;
>> + SlotIndexes *Indexes;
>> + LiveIntervals *LIS;
>> + const VirtRegMap *VRM;
>> + // True if this pass being run before virtual
>> registers are
>> remapped to
>> + // physical ones.
>> + bool PreRegRewrite;
>> + bool NoSubRegLiveness;
>> +
>> + protected:
>> + MachineCopyPropagation(char &ID, bool PreRegRewrite)
>> + : MachineFunctionPass(ID),
>> PreRegRewrite(PreRegRewrite) {}
>>
>> public:
>> static char ID; // Pass identification,
>> replacement for typeid
>> - MachineCopyPropagation() : MachineFunctionPass(ID) {
>> + MachineCopyPropagation() :
>> MachineCopyPropagation(ID, false) {
>> initializeMachineCopyPropagati
>> onPass(*PassRegistry::getPassRegistry());
>> }
>>
>> void getAnalysisUsage(AnalysisUsage &AU) const
>> override {
>> + if (PreRegRewrite) {
>> + AU.addRequired<SlotIndexes>();
>> + AU.addPreserved<SlotIndexes>();
>> + AU.addRequired<LiveIntervals>();
>> + AU.addPreserved<LiveIntervals>();
>> + AU.addRequired<VirtRegMap>();
>> + AU.addPreserved<VirtRegMap>();
>> + AU.addPreserved<LiveDebugVariables>();
>> + AU.addPreserved<LiveStacks>();
>> + }
>> AU.setPreservesCFG();
>> MachineFunctionPass::getAnalysisUsage(AU);
>> }
>> @@ -55,6 +123,10 @@ namespace {
>> bool runOnMachineFunction(MachineFunction &MF)
>> override;
>>
>> MachineFunctionProperties getRequiredProperties()
>> const override {
>> + if (PreRegRewrite)
>> + return MachineFunctionProperties()
>> + .set(MachineFunctionPropertie
>> s::Property::NoPHIs)
>> + .set(MachineFunctionPropertie
>> s::Property::TracksLiveness);
>> return MachineFunctionProperties().set(
>> MachineFunctionProperties::Pro
>> perty::NoVRegs);
>> }
>> @@ -64,6 +136,28 @@ namespace {
>> void ReadRegister(unsigned Reg);
>> void CopyPropagateBlock(MachineBasicBlock &MBB);
>> bool eraseIfRedundant(MachineInstr &Copy,
>> unsigned Src,
>> unsigned Def);
>> + unsigned getPhysReg(unsigned Reg, unsigned SubReg);
>> + unsigned getPhysReg(const MachineOperand &Opnd) {
>> + return getPhysReg(Opnd.getReg(),
>> Opnd.getSubReg());
>> + }
>> + unsigned getFullPhysReg(const MachineOperand &Opnd)
>> {
>> + return getPhysReg(Opnd.getReg(), 0);
>> + }
>> + void forwardUses(MachineInstr &MI);
>> + bool isForwardableRegClassCopy(const MachineInstr
>> &Copy,
>> + const MachineInstr
>> &UseI);
>> + std::tuple<unsigned, unsigned, bool>
>> + checkUseSubReg(const MachineOperand &CopySrc, const
>> MachineOperand &MOUse);
>> + bool hasImplicitOverlap(const MachineInstr &MI,
>> const
>> MachineOperand &Use);
>> + void narrowRegClass(const MachineInstr &MI, const
>> MachineOperand &MOUse,
>> + unsigned NewUseReg, unsigned
>> NewUseSubReg);
>> + void updateForwardedCopyLiveInterval(const
>> MachineInstr &Copy,
>> + const
>> MachineInstr &UseMI,
>> + unsigned
>> OrigUseReg,
>> + unsigned
>> NewUseReg,
>> + unsigned
>> NewUseSubReg);
>> + /// LiveRangeEdit callback for eliminateDeadDefs().
>> + void LRE_WillEraseInstruction(MachineInstr *MI)
>> override;
>>
>> /// Candidates for deletion.
>> SmallSetVector<MachineInstr*, 8> MaybeDeadCopies;
>> @@ -75,6 +169,15 @@ namespace {
>> SourceMap SrcMap;
>> bool Changed;
>> };
>> +
>> + class MachineCopyPropagationPreRegRewrite : public
>> MachineCopyPropagation {
>> + public:
>> + static char ID; // Pass identification,
>> replacement for typeid
>> + MachineCopyPropagationPreRegRewrite()
>> + : MachineCopyPropagation(ID, true) {
>> + initializeMachineCopyPropagat
>> ionPreRegRewritePass(*PassRegistry::getPassRegistry());
>> + }
>> + };
>> }
>> char MachineCopyPropagation::ID = 0;
>> char &llvm::MachineCopyPropagationID =
>> MachineCopyPropagation::ID;
>> @@ -82,6 +185,29 @@ char
>> &llvm::MachineCopyPropagationID = M
>> INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE,
>> "Machine Copy Propagation Pass",
>> false, false)
>>
>> +/// We have two separate passes that are very similar,
>> the only
>> difference being
>> +/// where they are meant to be run in the pipeline.
>> This is done
>> for several
>> +/// reasons:
>> +/// - the two passes have different dependencies
>> +/// - some targets want to disable the later run of
>> this pass, but
>> not the
>> +/// earlier one (e.g. NVPTX and WebAssembly)
>> +/// - it allows for easier debugging via llc
>> +
>> +char MachineCopyPropagationPreRegRewrite::ID = 0;
>> +char &llvm::MachineCopyPropagationPreRegRewriteID =
>> MachineCopyPropagationPreRegRewrite::ID;
>> +
>> +INITIALIZE_PASS_BEGIN(Machine
>> CopyPropagationPreRegRewrite,
>> + "machine-cp-prerewrite",
>> + "Machine Copy Propagation
>> Pre-Register
>> Rewrite Pass",
>> + false, false)
>> +INITIALIZE_PASS_DEPENDENCY(SlotIndexes)
>> +INITIALIZE_PASS_DEPENDENCY(LiveIntervals)
>> +INITIALIZE_PASS_DEPENDENCY(VirtRegMap)
>> +INITIALIZE_PASS_END(MachineCo
>> pyPropagationPreRegRewrite,
>> + "machine-cp-prerewrite",
>> + "Machine Copy Propagation
>> Pre-Register Rewrite
>> Pass", false,
>> + false)
>> +
>> /// Remove any entry in \p Map where the register is
>> a subregister
>> or equal to
>> /// a register contained in \p Regs.
>> static void removeRegsFromMap(Reg2MIMap &Map, const
>> RegList &Regs,
>> @@ -122,6 +248,10 @@ void
>> MachineCopyPropagation::ClobberRegi
>> }
>>
>> void MachineCopyPropagation::ReadRegister(unsigned
>> Reg) {
>> + // We don't track MaybeDeadCopies when running
>> pre-VirtRegRewriter.
>> + if (PreRegRewrite)
>> + return;
>> +
>> // If 'Reg' is defined by a copy, the copy is no
>> longer a candidate
>> // for elimination.
>> for (MCRegAliasIterator AI(Reg, TRI, true);
>> AI.isValid(); ++AI) {
>> @@ -153,6 +283,46 @@ static bool isNopCopy(const
>> MachineInstr
>> return SubIdx == TRI->getSubRegIndex(PreviousDef,
>> Def);
>> }
>>
>> +/// Return the physical register assigned to \p Reg if
>> it is a
>> virtual register,
>> +/// otherwise just return the physical reg from the
>> operand itself.
>> +///
>> +/// If \p SubReg is 0 then return the full physical
>> register
>> assigned to the
>> +/// virtual register ignoring subregs. If we aren't
>> tracking
>> sub-reg liveness
>> +/// then we need to use this to be more conservative
>> with clobbers
>> by killing
>> +/// all super reg and their sub reg COPYs as well.
>> This is to
>> prevent COPY
>> +/// forwarding in cases like the following:
>> +///
>> +/// %vreg2 = COPY %vreg1:sub1
>> +/// %vreg3 = COPY %vreg1:sub0
>> +/// ... = OP1 %vreg2
>> +/// ... = OP2 %vreg3
>> +///
>> +/// After forward %vreg2 (assuming this is the last
>> use of %vreg1) and
>> +/// VirtRegRewriter adding kill markers we have:
>> +///
>> +/// %vreg3 = COPY %vreg1:sub0
>> +/// ... = OP1 %vreg1:sub1<kill>
>> +/// ... = OP2 %vreg3
>> +///
>> +/// If %vreg3 is assigned to a sub-reg of %vreg1, then
>> after
>> rewriting we have:
>> +///
>> +/// ... = OP1 R0:sub1, R0<imp-use,kill>
>> +/// ... = OP2 R0:sub0
>> +///
>> +/// and the use of R0 by OP2 will not have a valid
>> definition.
>> +unsigned MachineCopyPropagation::getPhysReg(unsigned
>> Reg, unsigned
>> SubReg) {
>> +
>> + // Physical registers cannot have subregs.
>> + if (!TargetRegisterInfo::isVirtualRegister(Reg))
>> + return Reg;
>> +
>> + assert(PreRegRewrite && "Unexpected virtual register
>> encountered");
>> + Reg = VRM->getPhys(Reg);
>> + if (SubReg && !NoSubRegLiveness)
>> + Reg = TRI->getSubReg(Reg, SubReg);
>> + return Reg;
>> +}
>> +
>> /// Remove instruction \p Copy if there exists a
>> previous copy
>> that copies the
>> /// register \p Src to the register \p Def; This may
>> happen
>> indirectly by
>> /// copying the super registers.
>> @@ -190,6 +360,325 @@ bool
>> MachineCopyPropagation::eraseIfRedu
>> return true;
>> }
>>
>> +
>> +/// Decide whether we should forward the destination
>> of \param Copy
>> to its use
>> +/// in \param UseI based on the register class of the
>> Copy
>> operands. Same-class
>> +/// COPYs are always accepted by this function, but
>> cross-class
>> COPYs are only
>> +/// accepted if they are forwarded to another COPY
>> with the operand
>> register
>> +/// classes reversed. For example:
>> +///
>> +/// RegClassA = COPY RegClassB // Copy parameter
>> +/// ...
>> +/// RegClassB = COPY RegClassA // UseI parameter
>> +///
>> +/// which after forwarding becomes
>> +///
>> +/// RegClassA = COPY RegClassB
>> +/// ...
>> +/// RegClassB = COPY RegClassB
>> +///
>> +/// so we have reduced the number of cross-class COPYs
>> and potentially
>> +/// introduced a no COPY that can be removed.
>> +bool MachineCopyPropagation::isForwardableRegClassCopy(
>> + const MachineInstr &Copy, const MachineInstr &UseI)
>> {
>> + auto isCross = [&](const MachineOperand &Dst, const
>> MachineOperand &Src) {
>> + unsigned DstReg = Dst.getReg();
>> + unsigned SrcPhysReg = getPhysReg(Src);
>> + const TargetRegisterClass *DstRC;
>> + if (TargetRegisterInfo::isVirtualRegister(DstReg))
>> {
>> + DstRC = MRI->getRegClass(DstReg);
>> + unsigned DstSubReg = Dst.getSubReg();
>> + if (DstSubReg)
>> + SrcPhysReg = TRI->getMatchingSuperReg(SrcPh
>> ysReg,
>> DstSubReg, DstRC);
>> + } else
>> + DstRC = TRI->getMinimalPhysRegClass(DstReg);
>> +
>> + return !DstRC->contains(SrcPhysReg);
>> + };
>> +
>> + const MachineOperand &CopyDst = Copy.getOperand(0);
>> + const MachineOperand &CopySrc = Copy.getOperand(1);
>> +
>> + if (!isCross(CopyDst, CopySrc))
>> + return true;
>> +
>> + if (!UseI.isCopy())
>> + return false;
>> +
>> + assert(getFullPhysReg(UseI.getOperand(1)) ==
>> getFullPhysReg(CopyDst));
>> + return !isCross(UseI.getOperand(0), CopySrc);
>> +}
>> +
>> +/// Check that the subregs on the copy source operand
>> (\p CopySrc)
>> and the use
>> +/// operand to be forwarded to (\p MOUse) are
>> compatible with doing the
>> +/// forwarding. Also computes the new register and
>> subregister to
>> be used in
>> +/// the forwarded-to instruction.
>> +std::tuple<unsigned, unsigned, bool>
>> MachineCopyPropagation::checkUseSubReg(
>> + const MachineOperand &CopySrc, const
>> MachineOperand &MOUse) {
>> + unsigned NewUseReg = CopySrc.getReg();
>> + unsigned NewUseSubReg;
>> +
>> + if (TargetRegisterInfo::isPhysicalRegister(NewUseReg))
>> {
>> + // If MOUse is a virtual reg, we need to apply it
>> to the new
>> physical reg
>> + // we're going to replace it with.
>> + if (MOUse.getSubReg())
>> + NewUseReg = TRI->getSubReg(NewUseReg,
>> MOUse.getSubReg());
>> + // If the original use subreg isn't valid on the
>> new src reg,
>> we can't
>> + // forward it here.
>> + if (!NewUseReg)
>> + return std::make_tuple(0, 0, false);
>> + NewUseSubReg = 0;
>> + } else {
>> + // %v1 = COPY %v2:sub1
>> + // USE %v1:sub2
>> + // The new use is %v2:sub1:sub2
>> + NewUseSubReg =
>> + TRI->composeSubRegIndices(CopySrc.getSubReg(),
>> MOUse.getSubReg());
>> + // Check that NewUseSubReg is valid on NewUseReg
>> + if (NewUseSubReg &&
>> + !TRI->getSubClassWithSubReg(M
>> RI->getRegClass(NewUseReg),
>> NewUseSubReg))
>> + return std::make_tuple(0, 0, false);
>> + }
>> +
>> + return std::make_tuple(NewUseReg, NewUseSubReg, true);
>> +}
>> +
>> +/// Check that \p MI does not have implicit uses that
>> overlap with
>> it's \p Use
>> +/// operand (the register being replaced), since these
>> can sometimes be
>> +/// implicitly tied to other operands. For example,
>> on AMDGPU:
>> +///
>> +/// V_MOVRELS_B32_e32 %VGPR2, %M0<imp-use>,
>> %EXEC<imp-use>,
>> %VGPR2_VGPR3_VGPR4_VGPR5<imp-use>
>> +///
>> +/// the %VGPR2 is implicitly tied to the larger reg
>> operand, but we
>> have no
>> +/// way of knowing we need to update the latter when
>> updating the
>> former.
>> +bool MachineCopyPropagation::hasImplicitOverlap(const
>> MachineInstr &MI,
>> + const
>> MachineOperand &Use) {
>> + if
>> (!TargetRegisterInfo::isPhysicalRegister(Use.getReg()))
>> + return false;
>> +
>> + for (const MachineOperand &MIUse : MI.uses())
>> + if (&MIUse != &Use && MIUse.isReg() &&
>> MIUse.isImplicit() &&
>> + TRI->regsOverlap(Use.getReg(), MIUse.getReg()))
>> + return true;
>> +
>> + return false;
>> +}
>> +
>> +/// Narrow the register class of the forwarded vreg so
>> it matches any
>> +/// instruction constraints. \p MI is the instruction
>> being
>> forwarded to. \p
>> +/// MOUse is the operand being replaced in \p MI
>> (which hasn't yet
>> been updated
>> +/// at the time this function is called). \p
>> NewUseReg and \p
>> NewUseSubReg are
>> +/// what the \p MOUse will be changed to after
>> forwarding.
>> +///
>> +/// If we are forwarding
>> +/// A:RCA = COPY B:RCB
>> +/// into
>> +/// ... = OP A:RCA
>> +///
>> +/// then we need to narrow the register class of B so
>> that it is a
>> subclass
>> +/// of RCA so that it meets the instruction register
>> class constraints.
>> +void MachineCopyPropagation::narrowRegClass(const
>> MachineInstr &MI,
>> + const
>> MachineOperand
>> &MOUse,
>> + unsigned
>> NewUseReg,
>> + unsigned
>> NewUseSubReg) {
>> + if (!TargetRegisterInfo::isVirtua
>> lRegister(NewUseReg))
>> + return;
>> +
>> + // Make sure the virtual reg class allows the subreg.
>> + if (NewUseSubReg) {
>> + const TargetRegisterClass *CurUseRC =
>> MRI->getRegClass(NewUseReg);
>> + const TargetRegisterClass *NewUseRC =
>> + TRI->getSubClassWithSubReg(CurUseRC,
>> NewUseSubReg);
>> + if (CurUseRC != NewUseRC) {
>> + DEBUG(dbgs() << "MCP: Setting regclass of " <<
>> PrintReg(NewUseReg, TRI)
>> + << " to " <<
>> TRI->getRegClassName(NewUseRC) <<
>> "\n");
>> + MRI->setRegClass(NewUseReg, NewUseRC);
>> + }
>> + }
>> +
>> + unsigned MOUseOpNo = &MOUse - &MI.getOperand(0);
>> + const TargetRegisterClass *InstRC =
>> + TII->getRegClass(MI.getDesc(), MOUseOpNo, TRI,
>> *MF);
>> + if (InstRC) {
>> + const TargetRegisterClass *CurUseRC =
>> MRI->getRegClass(NewUseReg);
>> + if (NewUseSubReg)
>> + InstRC = TRI->getMatchingSuperRegClass(CurUseRC,
>> InstRC,
>> NewUseSubReg);
>> + if (!InstRC->hasSubClassEq(CurUseRC)) {
>> + const TargetRegisterClass *NewUseRC =
>> + TRI->getCommonSubClass(InstRC, CurUseRC);
>> + DEBUG(dbgs() << "MCP: Setting regclass of " <<
>> PrintReg(NewUseReg, TRI)
>> + << " to " <<
>> TRI->getRegClassName(NewUseRC) <<
>> "\n");
>> + MRI->setRegClass(NewUseReg, NewUseRC);
>> + }
>> + }
>> +}
>> +
>> +/// Update the LiveInterval information to reflect the
>> destination
>> of \p Copy
>> +/// being forwarded to a use in \p UseMI. \p
>> OrigUseReg is the
>> register being
>> +/// forwarded through. It should be the destination
>> register of \p
>> Copy and has
>> +/// already been replaced in \p UseMI at the point
>> this function is
>> called. \p
>> +/// NewUseReg and \p NewUseSubReg are the register and
>> subregister
>> being
>> +/// forwarded. They should be the source register of
>> the \p Copy
>> and should be
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20170823/5cdd6c65/attachment.html>
More information about the llvm-commits
mailing list