[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