<div dir="ltr">How long do you wait? it's OK if not output for a few minutes.</div><div class="gmail_extra"><br><div class="gmail_quote">On Tue, Aug 22, 2017 at 8:46 PM, Geoff Berry <span dir="ltr"><<a href="mailto:gberry@codeaurora.org" target="_blank">gberry@codeaurora.org</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">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:<br>
<br>
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?<br>
<br>
For the record I'm running:<br>
$ BUILDBOT_CLOBBER= BUILDBOT_REVISION=311142 ./buildbot_android.sh<br>
<br>
r311142 is my latest reversion of my MachineCopyPropagation changes<br>
and the only changes I've made to the scripts are:<br>
- change the svn repo to be https:// instead of http:// to avoid svn timeouts<br>
- 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<br>
<br>
It appears that the following tests are hanging:<br>
/data/local/tmp/Output/deep_ca<wbr>ll_stack.cc.tmp<br>
/data/local/tmp/Output/interce<wbr>ption_test.cc.tmp<br>
/data/local/tmp/Output/quarant<wbr>ine_size_mb.cc.tmp<br>
/data/local/tmp/Output/thread_<wbr><a href="http://local_quarantine_size_kb.cc.tm">local_quarantine_size_kb.cc.tm</a><wbr>p<br>
/data/local/tmp/Output/coverag<wbr>e-module-unloaded.cc.tmp.exe<br>
/data/local/tmp/Output/coverag<wbr>e-reset.cc.tmp<br>
/data/local/tmp/Output/coverag<wbr>e.cc.tmp<br>
/data/local/tmp/Output/start-d<wbr>eactivated.cc.tmp<br>
<br>
<br>
On 8/17/2017 9:24 PM, Vitaly Buka wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
If you have android with arm 32bit, you probably can reproduce with running <a href="https://llvm.org/svn/llvm-project/zorg/trunk/zorg/buildbot/builders/sanitizers/buildbot_android.sh" rel="noreferrer" target="_blank">https://llvm.org/svn/llvm-proj<wbr>ect/zorg/trunk/zorg/buildbot/<wbr>builders/sanitizers/buildbot_<wbr>android.sh</a> in empty directory.<br>
<br>
On Thu, Aug 17, 2017 at 6:23 PM, Vitaly Buka <<a href="mailto:vitalybuka@google.com" target="_blank">vitalybuka@google.com</a> <mailto:<a href="mailto:vitalybuka@google.com" target="_blank">vitalybuka@google.com</a>><wbr>> wrote:<br>
<br>
    I just hangs on "Running the AddressSanitizer tests" for arm<br>
<br>
    /var/lib/buildbot/sanitizer-bu<wbr>ildbot6/sanitizer-x86_64-linux<wbr>-android/build/compiler_rt_<wbr>build_android_arm/lib/asan/tes<wbr>ts/AsanTest:<br>
    1 file pus<br>
    hed. 3.7 MB/s (10602792 bytes in 2.742s)<br>
    + echo @@@BUILD_STEP run asan lit tests<br>
    '[arm/sailfish-userdebug/OPR1.<wbr>170621.001]@@@'<br>
    @@@BUILD_STEP run asan lit tests<br>
    [arm/sailfish-userdebug/OPR1.1<wbr>70621.001]@@@<br>
    + cd<br>
    /var/lib/buildbot/sanitizer-bu<wbr>ildbot6/sanitizer-x86_64-linux<wbr>-android/build/compiler_rt_<wbr>build_android_arm<br>
    + ninja check-asan<br>
    [1/1] Running the AddressSanitizer tests<br>
<br>
<br>
    But the same device passes aarch64 tests:<br>
    [1/1] Running the AddressSanitizer tests<br>
    -- Testing: 407 tests, 12 threads --<br>
    Testing: 0 .. 10.. 20.. 30.. 40.. 50.. 60.. 70.. 80.. 90..<br>
    Testing Time: 87.09s<br>
       Expected Passes    : 202<br>
       Expected Failures  : 27<br>
       Unsupported Tests  : 178<br>
    + echo @@@BUILD_STEP run sanitizer_common tests<br>
    '[aarch64/sailfish-userdebug/O<wbr>PR1.170621.001]@@@'<br>
    @@@BUILD_STEP run sanitizer_common tests<br>
    [aarch64/sailfish-userdebug/OP<wbr>R1.170621.001]@@@<br>
<br>
<br>
<br>
    On Thu, Aug 17, 2017 at 5:42 PM, Geoff Berry <<a href="mailto:gberry@codeaurora.org" target="_blank">gberry@codeaurora.org</a><br>
    <mailto:<a href="mailto:gberry@codeaurora.org" target="_blank">gberry@codeaurora.org</a>><wbr>> wrote:<br>
<br>
        It seems like this is still happening after fixing a couple of<br>
        issues with this patch.  I'll revert again shortly.  I'm having<br>
        a hard time understanding what is failing from looking at the<br>
        buildbot logs though. Do you have any way of determining what<br>
        exactly is timing out?<br>
<br>
        On 8/16/2017 11:13 PM, Vitaly Buka wrote:<br>
<br>
            Looks like after this patch Android tests consistently hang<br>
            <a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-android/builds/1825" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/build<wbr>ers/sanitizer-x86_64-linux-<wbr>android/builds/1825</a><br>
            <<a href="http://lab.llvm.org:8011/builders/sanitizer-x86_64-linux-android/builds/1825" rel="noreferrer" target="_blank">http://lab.llvm.org:8011/buil<wbr>ders/sanitizer-x86_64-linux-<wbr>android/builds/1825</a>><br>
<br>
            On Wed, Aug 16, 2017 at 1:50 PM, Geoff Berry via<br>
            llvm-commits <<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llvm.org</a><br>
            <mailto:<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llv<wbr>m.org</a>><br>
            <mailto:<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llv<wbr>m.org</a><br>
            <mailto:<a href="mailto:llvm-commits@lists.llvm.org" target="_blank">llvm-commits@lists.llv<wbr>m.org</a>>>> wrote:<br>
<br>
                 Author: gberry<br>
                 Date: Wed Aug 16 13:50:01 2017<br>
                 New Revision: 311038<br>
<br>
                 URL:<br>
            <a href="http://llvm.org/viewvc/llvm-project?rev=311038&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject?rev=311038&view=rev</a><br>
            <<a href="http://llvm.org/viewvc/llvm-project?rev=311038&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject?rev=311038&view=rev</a>><br>
                            <<a href="http://llvm.org/viewvc/llvm-project?rev=311038&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject?rev=311038&view=rev</a><br>
            <<a href="http://llvm.org/viewvc/llvm-project?rev=311038&view=rev" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject?rev=311038&view=rev</a>>><br>
                 Log:<br>
                 [MachineCopyPropagation] Extend pass to do COPY source<br>
            forwarding<br>
<br>
                 This change extends MachineCopyPropagation to do COPY<br>
            source forwarding.<br>
<br>
                 This change also extends the MachineCopyPropagation<br>
            pass to be able to<br>
                 be run during register allocation, after physical<br>
            registers have been<br>
                 assigned, but before the virtual registers have been<br>
            re-written, which<br>
                 allows it to remove virtual register COPY LiveIntervals<br>
            that become dead<br>
                 through the forwarding of all of their uses.<br>
<br>
                 Reviewers: qcolombet, javed.absar, MatzeB, jonpa<br>
<br>
                 Subscribers: jyknight, nemanjai, llvm-commits,<br>
            nhaehnle, mcrosier,<br>
                 mgorny<br>
<br>
                 Differential Revision: <a href="https://reviews.llvm.org/D30751" rel="noreferrer" target="_blank">https://reviews.llvm.org/D3075<wbr>1</a><br>
            <<a href="https://reviews.llvm.org/D30751" rel="noreferrer" target="_blank">https://reviews.llvm.org/D307<wbr>51</a>><br>
                 <<a href="https://reviews.llvm.org/D30751" rel="noreferrer" target="_blank">https://reviews.llvm.org/D307<wbr>51</a><br>
            <<a href="https://reviews.llvm.org/D30751" rel="noreferrer" target="_blank">https://reviews.llvm.org/D307<wbr>51</a>>><br>
<br>
                 Modified:<br>
                      llvm/trunk/include/llvm/CodeG<wbr>en/Passes.h<br>
                      llvm/trunk/include/llvm/Initi<wbr>alizePasses.h<br>
                      llvm/trunk/lib/CodeGen/CodeGe<wbr>n.cpp<br>
                      llvm/trunk/lib/CodeGen/Machin<wbr>eCopyPropagation.cpp<br>
                      llvm/trunk/lib/CodeGen/Target<wbr>PassConfig.cpp<br>
                                  llvm/trunk/test/CodeGen/AArc<wbr>h64/aarch64-fold-lslfast.ll<br>
                                  llvm/trunk/test/CodeGen/AArc<wbr>h64/arm64-AdvSIMD-Scalar.ll<br>
                                  llvm/trunk/test/CodeGen/AArc<wbr>h64/arm64-zero-cycle-regmov.ll<br>
                      llvm/trunk/test/CodeGen/AArch<wbr>64/f16-instructions.ll<br>
                      llvm/trunk/test/CodeGen/AArch<wbr>64/flags-multiuse.ll<br>
                                  llvm/trunk/test/CodeGen/AArc<wbr>h64/merge-store-dependency.ll<br>
                      llvm/trunk/test/CodeGen/AArch<wbr>64/neg-imm.ll<br>
                      llvm/trunk/test/CodeGen/AMDGP<wbr>U/byval-frame-setup.ll<br>
                      llvm/trunk/test/CodeGen/AMDGP<wbr>U/call-argument-types.ll<br>
                                  llvm/trunk/test/CodeGen/AMDG<wbr>PU/call-preserved-registers.ll<br>
                                  llvm/trunk/test/CodeGen/AMDG<wbr>PU/callee-special-input-sgprs.<wbr>ll<br>
                                  llvm/trunk/test/CodeGen/AMDG<wbr>PU/callee-special-input-vgprs.<wbr>ll<br>
                      llvm/trunk/test/CodeGen/AMDGP<wbr>U/mubuf-offset-private.ll<br>
                      llvm/trunk/test/CodeGen/AMDGP<wbr>U/multilevel-break.ll<br>
                                  llvm/trunk/test/CodeGen/AMDG<wbr>PU/private-access-no-objects.<wbr>ll<br>
                      llvm/trunk/test/CodeGen/AMDGP<wbr>U/ret.ll<br>
                      llvm/trunk/test/CodeGen/ARM/a<wbr>tomic-op.ll<br>
                      llvm/trunk/test/CodeGen/ARM/s<wbr>wifterror.ll<br>
                      llvm/trunk/test/CodeGen/Mips/<wbr>llvm-ir/sub.ll<br>
                      llvm/trunk/test/CodeGen/Power<wbr>PC/fma-mutate.ll<br>
                      llvm/trunk/test/CodeGen/Power<wbr>PC/inlineasm-i64-reg.ll<br>
                      llvm/trunk/test/CodeGen/Power<wbr>PC/tail-dup-layout.ll<br>
                      llvm/trunk/test/CodeGen/SPARC<wbr>/32abi.ll<br>
                      llvm/trunk/test/CodeGen/SPARC<wbr>/atomics.ll<br>
                      llvm/trunk/test/CodeGen/Thumb<wbr>/thumb-shrink-wrapping.ll<br>
                                  llvm/trunk/test/CodeGen/X86/<wbr>2006-03-01-InstrSchedBug.ll<br>
                      llvm/trunk/test/CodeGen/X86/a<wbr>rg-copy-elide.ll<br>
                      llvm/trunk/test/CodeGen/X86/a<wbr>vg.ll<br>
                      llvm/trunk/test/CodeGen/X86/a<wbr>vx-load-store.ll<br>
                      llvm/trunk/test/CodeGen/X86/a<wbr>vx512-bugfix-25270.ll<br>
                      llvm/trunk/test/CodeGen/X86/a<wbr>vx512-calling-conv.ll<br>
                      llvm/trunk/test/CodeGen/X86/a<wbr>vx512-mask-op.ll<br>
                                  llvm/trunk/test/CodeGen/X86/<wbr>avx512bw-intrinsics-upgrade.ll<br>
                                  llvm/trunk/test/CodeGen/X86/<wbr>bitcast-int-to-vector-bool-sex<wbr>t.ll<br>
                                  llvm/trunk/test/CodeGen/X86/<wbr>bitcast-int-to-vector-bool-zex<wbr>t.ll<br>
                      llvm/trunk/test/CodeGen/X86/b<wbr>uildvec-insertvec.ll<br>
                      llvm/trunk/test/CodeGen/X86/c<wbr>ombine-fcopysign.ll<br>
                      llvm/trunk/test/CodeGen/X86/c<wbr>omplex-fastmath.ll<br>
                      llvm/trunk/test/CodeGen/X86/d<wbr>ivide-by-constant.ll<br>
                      llvm/trunk/test/CodeGen/X86/f<wbr>maxnum.ll<br>
                      llvm/trunk/test/CodeGen/X86/f<wbr>minnum.ll<br>
                      llvm/trunk/test/CodeGen/X86/f<wbr>p128-i128.ll<br>
                      llvm/trunk/test/CodeGen/X86/h<wbr>addsub-2.ll<br>
                      llvm/trunk/test/CodeGen/X86/h<wbr>addsub-undef.ll<br>
                      llvm/trunk/test/CodeGen/X86/h<wbr>alf.ll<br>
                      llvm/trunk/test/CodeGen/X86/i<wbr>nline-asm-fpstack.ll<br>
                      llvm/trunk/test/CodeGen/X86/i<wbr>pra-local-linkage.ll<br>
                      llvm/trunk/test/CodeGen/X86/l<wbr>ocalescape.ll<br>
                      llvm/trunk/test/CodeGen/X86/m<wbr>ul-i1024.ll<br>
                      llvm/trunk/test/CodeGen/X86/m<wbr>ul-i512.ll<br>
                      llvm/trunk/test/CodeGen/X86/m<wbr>ul128.ll<br>
                      llvm/trunk/test/CodeGen/X86/p<wbr>mul.ll<br>
                      llvm/trunk/test/CodeGen/X86/p<wbr>owi.ll<br>
                      llvm/trunk/test/CodeGen/X86/p<wbr>r11334.ll<br>
                      llvm/trunk/test/CodeGen/X86/p<wbr>r29112.ll<br>
                      llvm/trunk/test/CodeGen/X86/p<wbr>subus.ll<br>
                      llvm/trunk/test/CodeGen/X86/s<wbr>elect.ll<br>
                      llvm/trunk/test/CodeGen/X86/s<wbr>hrink-wrap-chkstk.ll<br>
                      llvm/trunk/test/CodeGen/X86/s<wbr>qrt-fastmath.ll<br>
                      llvm/trunk/test/CodeGen/X86/s<wbr>se-scalar-fp-arith.ll<br>
                      llvm/trunk/test/CodeGen/X86/s<wbr>se1.ll<br>
                      llvm/trunk/test/CodeGen/X86/s<wbr>se3-avx-addsub-2.ll<br>
                      llvm/trunk/test/CodeGen/X86/s<wbr>tatepoint-live-in.ll<br>
                      llvm/trunk/test/CodeGen/X86/s<wbr>tatepoint-stack-usage.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ec_fp_to_int.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ec_int_to_fp.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ec_minmax_sint.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ec_shift4.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ector-blend.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ector-idiv-sdiv-128.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ector-idiv-udiv-128.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ector-rotate-128.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ector-sext.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ector-shift-ashr-128.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ector-shift-lshr-128.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ector-shift-shl-128.ll<br>
                                  llvm/trunk/test/CodeGen/X86/<wbr>vector-shuffle-combining.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ector-trunc-math.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>ector-zext.ll<br>
                      llvm/trunk/test/CodeGen/X86/v<wbr>select-minmax.ll<br>
                      llvm/trunk/test/CodeGen/X86/w<wbr>iden_conv-3.ll<br>
                      llvm/trunk/test/CodeGen/X86/w<wbr>iden_conv-4.ll<br>
                      llvm/trunk/test/CodeGen/X86/x<wbr>86-shrink-wrap-unwind.ll<br>
                      llvm/trunk/test/CodeGen/X86/x<wbr>86-shrink-wrapping.ll<br>
<br>
                 Modified: llvm/trunk/include/llvm/CodeGe<wbr>n/Passes.h<br>
                 URL:<br>
            <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/include/llvm/<wbr>CodeGen/Passes.h?rev=311038&<wbr>r1=311037&r2=311038&view=diff</a><br>
            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/include/llvm<wbr>/CodeGen/Passes.h?rev=311038&<wbr>r1=311037&r2=311038&view=diff</a>><br>
                            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/include/llvm<wbr>/CodeGen/Passes.h?rev=311038&<wbr>r1=311037&r2=311038&view=diff</a><br>
            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/Passes.h?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/include/llvm<wbr>/CodeGen/Passes.h?rev=311038&<wbr>r1=311037&r2=311038&view=diff</a>><wbr>><br>
                            ==============================<wbr>==============================<wbr>==================<br>
                 --- llvm/trunk/include/llvm/CodeGe<wbr>n/Passes.h (original)<br>
                 +++ llvm/trunk/include/llvm/CodeGe<wbr>n/Passes.h Wed Aug 16<br>
            13:50:01 2017<br>
                 @@ -278,6 +278,11 @@ namespace llvm {<br>
                     /// MachineSinking - This pass performs sinking on<br>
            machine<br>
                 instructions.<br>
                     extern char &MachineSinkingID;<br>
<br>
                 +  /// MachineCopyPropagationPreRegRe<wbr>write - This pass<br>
            performs copy<br>
                 propagation<br>
                 +  /// on machine instructions after register<br>
            allocation but before<br>
                 virtual<br>
                 +  /// register re-writing..<br>
                 +  extern char &MachineCopyPropagationPreRegR<wbr>ewriteID;<br>
                 +<br>
                     /// MachineCopyPropagation - This pass performs<br>
            copy propagation on<br>
                     /// machine instructions.<br>
                     extern char &MachineCopyPropagationID;<br>
<br>
                 Modified: llvm/trunk/include/llvm/Initia<wbr>lizePasses.h<br>
                 URL:<br>
            <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/include/llvm/<wbr>InitializePasses.h?rev=311038&<wbr>r1=311037&r2=311038&view=diff</a><br>
            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/include/llvm<wbr>/InitializePasses.h?rev=311038<wbr>&r1=311037&r2=311038&view=diff</a><wbr>><br>
                            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/include/llvm<wbr>/InitializePasses.h?rev=311038<wbr>&r1=311037&r2=311038&view=diff</a><br>
            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/InitializePasses.h?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/include/llvm<wbr>/InitializePasses.h?rev=311038<wbr>&r1=311037&r2=311038&view=diff</a><wbr>>><br>
                            ==============================<wbr>==============================<wbr>==================<br>
                 --- llvm/trunk/include/llvm/Initia<wbr>lizePasses.h (original)<br>
                 +++ llvm/trunk/include/llvm/Initia<wbr>lizePasses.h Wed Aug<br>
            16 13:50:01 2017<br>
                 @@ -233,6 +233,7 @@ void<br>
            initializeMachineBranchProbabi<wbr>lityI<br>
                   void initializeMachineCSEPass(PassR<wbr>egistry&);<br>
                   void initializeMachineCombinerPass(<wbr>PassRegistry&);<br>
                   void initializeMachineCopyPropagati<wbr>onPass(PassRegistry&);<br>
                 +void<br>
            initializeMachineCopyPropagati<wbr>onPreRegRewritePass(PassRegist<wbr>ry&);<br>
                   void<br>
            initializeMachineDominanceFron<wbr>tierPass(PassRegistry&);<br>
                   void initializeMachineDominatorTree<wbr>Pass(PassRegistry&);<br>
                   void<br>
            initializeMachineFunctionPrint<wbr>erPassPass(PassRegistry&);<br>
<br>
                 Modified: llvm/trunk/lib/CodeGen/CodeGen<wbr>.cpp<br>
                 URL:<br>
            <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGen.cpp?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/CodeGen/<wbr>CodeGen.cpp?rev=311038&r1=<wbr>311037&r2=311038&view=diff</a><br>
            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGen.cpp?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/lib/CodeGen/<wbr>CodeGen.cpp?rev=311038&r1=<wbr>311037&r2=311038&view=diff</a>><br>
                            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGen.cpp?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/lib/CodeGen/<wbr>CodeGen.cpp?rev=311038&r1=<wbr>311037&r2=311038&view=diff</a><br>
            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/CodeGen.cpp?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/lib/CodeGen/<wbr>CodeGen.cpp?rev=311038&r1=<wbr>311037&r2=311038&view=diff</a>>><br>
                            ==============================<wbr>==============================<wbr>==================<br>
                 --- llvm/trunk/lib/CodeGen/CodeGen<wbr>.cpp (original)<br>
                 +++ llvm/trunk/lib/CodeGen/CodeGen<wbr>.cpp Wed Aug 16<br>
            13:50:01 2017<br>
                 @@ -54,6 +54,7 @@ void llvm::initializeCodeGen(PassRe<wbr>gistr<br>
                     initializeMachineCSEPass(Regis<wbr>try);<br>
                     initializeMachineCombinerPass(<wbr>Registry);<br>
                     initializeMachineCopyPropagati<wbr>onPass(Registry);<br>
                 +             <wbr>initializeMachineCopyPropagati<wbr>onPreRegRewritePass(Registry);<br>
                     initializeMachineDominatorTree<wbr>Pass(Registry);<br>
                     initializeMachineFunctionPrint<wbr>erPassPass(Registry);<br>
                     initializeMachineLICMPass(Regi<wbr>stry);<br>
<br>
                 Modified: llvm/trunk/lib/CodeGen/Machine<wbr>CopyPropagation.cpp<br>
                 URL:<br>
            <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-pr<wbr>oject/llvm/trunk/lib/CodeGen/M<wbr>achineCopyPropagation.cpp?rev=<wbr>311038&r1=311037&r2=311038&<wbr>view=diff</a><br>
            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/lib/CodeGen/<wbr>MachineCopyPropagation.cpp?rev<wbr>=311038&r1=311037&r2=311038&<wbr>view=diff</a>><br>
                            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/lib/CodeGen/<wbr>MachineCopyPropagation.cpp?rev<wbr>=311038&r1=311037&r2=311038&<wbr>view=diff</a><br>
            <<a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp?rev=311038&r1=311037&r2=311038&view=diff" rel="noreferrer" target="_blank">http://llvm.org/viewvc/llvm-p<wbr>roject/llvm/trunk/lib/CodeGen/<wbr>MachineCopyPropagation.cpp?rev<wbr>=311038&r1=311037&r2=311038&<wbr>view=diff</a>>><br>
                            ==============================<wbr>==============================<wbr>==================<br>
                 --- llvm/trunk/lib/CodeGen/Machine<wbr>CopyPropagation.cpp<br>
            (original)<br>
                 +++ llvm/trunk/lib/CodeGen/Machine<wbr>CopyPropagation.cpp<br>
            Wed Aug 16<br>
                 13:50:01 2017<br>
                 @@ -7,18 +7,62 @@<br>
                   //<br>
                              //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
                   //<br>
                 -// This is an extremely simple MachineInstr-level copy<br>
            propagation<br>
                 pass.<br>
                 +// This is a simple MachineInstr-level copy forwarding<br>
            pass.  It<br>
                 may be run at<br>
                 +// two places in the codegen pipeline:<br>
                 +//   - After register allocation but before virtual<br>
            registers have<br>
                 been remapped<br>
                 +//     to physical registers.<br>
                 +//   - After physical register remapping.<br>
                 +//<br>
                 +// The optimizations done vary slightly based on<br>
            whether virtual<br>
                 registers are<br>
                 +// still present.  In both cases, this pass forwards<br>
            the source of<br>
                 COPYs to the<br>
                 +// users of their destinations when doing so is<br>
            legal.  For example:<br>
                 +//<br>
                 +//   %vreg1 = COPY %vreg0<br>
                 +//   ...<br>
                 +//   ... = OP %vreg1<br>
                 +//<br>
                 +// If<br>
                 +//   - the physical register assigned to %vreg0 has<br>
            not been<br>
                 clobbered by the<br>
                 +//     time of the use of %vreg1<br>
                 +//   - the register class constraints are satisfied<br>
                 +//   - the COPY def is the only value that reaches OP<br>
                 +// then this pass replaces the above with:<br>
                 +//<br>
                 +//   %vreg1 = COPY %vreg0<br>
                 +//   ...<br>
                 +//   ... = OP %vreg0<br>
                 +//<br>
                 +// and updates the relevant state required by<br>
            VirtRegMap (e.g.<br>
                 LiveIntervals).<br>
                 +// COPYs whose LiveIntervals become dead as a result<br>
            of this<br>
                 forwarding (i.e. if<br>
                 +// all uses of %vreg1 are changed to %vreg0) are removed.<br>
                 +//<br>
                 +// When being run with only physical registers, this<br>
            pass will also<br>
                 remove some<br>
                 +// redundant COPYs.  For example:<br>
                 +//<br>
                 +//    %R1 = COPY %R0<br>
                 +//    ... // No clobber of %R1<br>
                 +//    %R0 = COPY %R1 <<< Removed<br>
                 +//<br>
                 +// or<br>
                 +//<br>
                 +//    %R1 = COPY %R0<br>
                 +//    ... // No clobber of %R0<br>
                 +//    %R1 = COPY %R0 <<< Removed<br>
                   //<br>
                              //===-------------------------<wbr>------------------------------<wbr>---------------===//<br>
<br>
                 +#include "LiveDebugVariables.h"<br>
                   #include "llvm/ADT/DenseMap.h"<br>
                   #include "llvm/ADT/SetVector.h"<br>
                   #include "llvm/ADT/SmallVector.h"<br>
                   #include "llvm/ADT/Statistic.h"<br>
                 +#include "llvm/CodeGen/LiveRangeEdit.h"<br>
                 +#include "llvm/CodeGen/LiveStackAnalysi<wbr>s.h"<br>
                   #include "llvm/CodeGen/MachineFunction.<wbr>h"<br>
                   #include "llvm/CodeGen/MachineFunctionP<wbr>ass.h"<br>
                   #include "llvm/CodeGen/MachineRegisterI<wbr>nfo.h"<br>
                   #include "llvm/CodeGen/Passes.h"<br>
                 +#include "llvm/CodeGen/VirtRegMap.h"<br>
                   #include "llvm/Pass.h"<br>
                   #include "llvm/Support/Debug.h"<br>
                   #include "llvm/Support/raw_ostream.h"<br>
                 @@ -30,24 +74,48 @@ using namespace llvm;<br>
                   #define DEBUG_TYPE "machine-cp"<br>
<br>
                   STATISTIC(NumDeletes, "Number of dead copies deleted");<br>
                 +STATISTIC(NumCopyForwards, "Number of copy uses<br>
            forwarded");<br>
<br>
                   namespace {<br>
                     typedef SmallVector<unsigned, 4> RegList;<br>
                     typedef DenseMap<unsigned, RegList> SourceMap;<br>
                     typedef DenseMap<unsigned, MachineInstr*> Reg2MIMap;<br>
<br>
                 -  class MachineCopyPropagation : public<br>
            MachineFunctionPass {<br>
                 +  class MachineCopyPropagation : public<br>
            MachineFunctionPass,<br>
                 +                                 private<br>
            LiveRangeEdit::Delegate {<br>
                       const TargetRegisterInfo *TRI;<br>
                       const TargetInstrInfo *TII;<br>
                 -    const MachineRegisterInfo *MRI;<br>
                 +    MachineRegisterInfo *MRI;<br>
                 +    MachineFunction *MF;<br>
                 +    SlotIndexes *Indexes;<br>
                 +    LiveIntervals *LIS;<br>
                 +    const VirtRegMap *VRM;<br>
                 +    // True if this pass being run before virtual<br>
            registers are<br>
                 remapped to<br>
                 +    // physical ones.<br>
                 +    bool PreRegRewrite;<br>
                 +    bool NoSubRegLiveness;<br>
                 +<br>
                 +  protected:<br>
                 +    MachineCopyPropagation(char &ID, bool PreRegRewrite)<br>
                 +        : MachineFunctionPass(ID),<br>
            PreRegRewrite(PreRegRewrite) {}<br>
<br>
                     public:<br>
                       static char ID; // Pass identification,<br>
            replacement for typeid<br>
                 -    MachineCopyPropagation() : MachineFunctionPass(ID) {<br>
                 +    MachineCopyPropagation() :<br>
            MachineCopyPropagation(ID, false) {<br>
                                        initializeMachineCopyPropagati<wbr>onPass(*PassRegistry::getPassR<wbr>egistry());<br>
                       }<br>
<br>
                       void getAnalysisUsage(AnalysisUsage &AU) const<br>
            override {<br>
                 +      if (PreRegRewrite) {<br>
                 +        AU.addRequired<SlotIndexes>();<br>
                 +        AU.addPreserved<SlotIndexes>()<wbr>;<br>
                 +        AU.addRequired<LiveIntervals>(<wbr>);<br>
                 +        AU.addPreserved<LiveIntervals><wbr>();<br>
                 +        AU.addRequired<VirtRegMap>();<br>
                 +        AU.addPreserved<VirtRegMap>();<br>
                 +        AU.addPreserved<LiveDebugVaria<wbr>bles>();<br>
                 +        AU.addPreserved<LiveStacks>();<br>
                 +      }<br>
                         AU.setPreservesCFG();<br>
                         MachineFunctionPass::getAnalys<wbr>isUsage(AU);<br>
                       }<br>
                 @@ -55,6 +123,10 @@ namespace {<br>
                       bool runOnMachineFunction(MachineFu<wbr>nction &MF)<br>
            override;<br>
<br>
                       MachineFunctionProperties getRequiredProperties()<br>
            const override {<br>
                 +      if (PreRegRewrite)<br>
                 +        return MachineFunctionProperties()<br>
                 +                       .set(MachineFunctionPropertie<wbr>s::Property::NoPHIs)<br>
                 +                       .set(MachineFunctionPropertie<wbr>s::Property::TracksLiveness);<br>
                         return MachineFunctionProperties().se<wbr>t(<br>
                             MachineFunctionProperties::Pro<wbr>perty::NoVRegs);<br>
                       }<br>
                 @@ -64,6 +136,28 @@ namespace {<br>
                       void ReadRegister(unsigned Reg);<br>
                       void CopyPropagateBlock(MachineBasi<wbr>cBlock &MBB);<br>
                       bool eraseIfRedundant(MachineInstr &Copy,<br>
            unsigned Src,<br>
                 unsigned Def);<br>
                 +    unsigned getPhysReg(unsigned Reg, unsigned SubReg);<br>
                 +    unsigned getPhysReg(const MachineOperand &Opnd) {<br>
                 +      return getPhysReg(Opnd.getReg(), Opnd.getSubReg());<br>
                 +    }<br>
                 +    unsigned getFullPhysReg(const MachineOperand &Opnd) {<br>
                 +      return getPhysReg(Opnd.getReg(), 0);<br>
                 +    }<br>
                 +    void forwardUses(MachineInstr &MI);<br>
                 +    bool isForwardableRegClassCopy(cons<wbr>t MachineInstr<br>
            &Copy,<br>
                 +                                   const MachineInstr<br>
            &UseI);<br>
                 +    std::tuple<unsigned, unsigned, bool><br>
                 +    checkUseSubReg(const MachineOperand &CopySrc, const<br>
                 MachineOperand &MOUse);<br>
                 +    bool hasImplicitOverlap(const MachineInstr &MI, const<br>
                 MachineOperand &Use);<br>
                 +    void narrowRegClass(const MachineInstr &MI, const<br>
                 MachineOperand &MOUse,<br>
                 +                        unsigned NewUseReg, unsigned<br>
            NewUseSubReg);<br>
                 +    void updateForwardedCopyLiveInterva<wbr>l(const<br>
            MachineInstr &Copy,<br>
                 +                                         const<br>
            MachineInstr &UseMI,<br>
                 +                                         unsigned<br>
            OrigUseReg,<br>
                 +                                         unsigned<br>
            NewUseReg,<br>
                 +                                         unsigned<br>
            NewUseSubReg);<br>
                 +    /// LiveRangeEdit callback for eliminateDeadDefs().<br>
                 +    void LRE_WillEraseInstruction(Machi<wbr>neInstr *MI)<br>
            override;<br>
<br>
                       /// Candidates for deletion.<br>
                       SmallSetVector<MachineInstr*, 8> MaybeDeadCopies;<br>
                 @@ -75,6 +169,15 @@ namespace {<br>
                       SourceMap SrcMap;<br>
                       bool Changed;<br>
                     };<br>
                 +<br>
                 +  class MachineCopyPropagationPreRegRe<wbr>write : public<br>
                 MachineCopyPropagation {<br>
                 +  public:<br>
                 +    static char ID; // Pass identification,<br>
            replacement for typeid<br>
                 +    MachineCopyPropagationPreRegRe<wbr>write()<br>
                 +        : MachineCopyPropagation(ID, true) {<br>
                 +                     initializeMachineCopyPropagat<wbr>ionPreRegRewritePass(*PassRegi<wbr>stry::getPassRegistry());<br>
                 +    }<br>
                 +  };<br>
                   }<br>
                   char MachineCopyPropagation::ID = 0;<br>
                   char &llvm::MachineCopyPropagationI<wbr>D =<br>
            MachineCopyPropagation::ID;<br>
                 @@ -82,6 +185,29 @@ char<br>
            &llvm::MachineCopyPropagationI<wbr>D = M<br>
                   INITIALIZE_PASS(MachineCopyPro<wbr>pagation, DEBUG_TYPE,<br>
                                   "Machine Copy Propagation Pass",<br>
            false, false)<br>
<br>
                 +/// We have two separate passes that are very similar,<br>
            the only<br>
                 difference being<br>
                 +/// where they are meant to be run in the pipeline.             This is done<br>
                 for several<br>
                 +/// reasons:<br>
                 +/// - the two passes have different dependencies<br>
                 +/// - some targets want to disable the later run of<br>
            this pass, but<br>
                 not the<br>
                 +///   earlier one (e.g. NVPTX and WebAssembly)<br>
                 +/// - it allows for easier debugging via llc<br>
                 +<br>
                 +char MachineCopyPropagationPreRegRe<wbr>write::ID = 0;<br>
                 +char &llvm::MachineCopyPropagationP<wbr>reRegRewriteID =<br>
                 MachineCopyPropagationPreRegRe<wbr>write::ID;<br>
                 +<br>
                 +INITIALIZE_PASS_BEGIN(Machine<wbr>CopyPropagationPreRegRewrite,<br>
                 +                      "machine-cp-prerewrite",<br>
                 +                      "Machine Copy Propagation<br>
            Pre-Register<br>
                 Rewrite Pass",<br>
                 +                      false, false)<br>
                 +INITIALIZE_PASS_DEPENDENCY(Sl<wbr>otIndexes)<br>
                 +INITIALIZE_PASS_DEPENDENCY(Li<wbr>veIntervals)<br>
                 +INITIALIZE_PASS_DEPENDENCY(Vi<wbr>rtRegMap)<br>
                 +INITIALIZE_PASS_END(MachineCo<wbr>pyPropagationPreRegRewrite,<br>
                 +                    "machine-cp-prerewrite",<br>
                 +                    "Machine Copy Propagation<br>
            Pre-Register Rewrite<br>
                 Pass", false,<br>
                 +                    false)<br>
                 +<br>
                   /// Remove any entry in \p Map where the register is<br>
            a subregister<br>
                 or equal to<br>
                   /// a register contained in \p Regs.<br>
                   static void removeRegsFromMap(Reg2MIMap &Map, const<br>
            RegList &Regs,<br>
                 @@ -122,6 +248,10 @@ void<br>
            MachineCopyPropagation::Clobbe<wbr>rRegi<br>
                   }<br>
<br>
                   void MachineCopyPropagation::ReadRe<wbr>gister(unsigned Reg) {<br>
                 +  // We don't track MaybeDeadCopies when running<br>
            pre-VirtRegRewriter.<br>
                 +  if (PreRegRewrite)<br>
                 +    return;<br>
                 +<br>
                     // If 'Reg' is defined by a copy, the copy is no<br>
            longer a candidate<br>
                     // for elimination.<br>
                     for (MCRegAliasIterator AI(Reg, TRI, true);<br>
            AI.isValid(); ++AI) {<br>
                 @@ -153,6 +283,46 @@ static bool isNopCopy(const<br>
            MachineInstr<br>
                     return SubIdx == TRI->getSubRegIndex(PreviousDe<wbr>f, Def);<br>
                   }<br>
<br>
                 +/// Return the physical register assigned to \p Reg if<br>
            it is a<br>
                 virtual register,<br>
                 +/// otherwise just return the physical reg from the<br>
            operand itself.<br>
                 +///<br>
                 +/// If \p SubReg is 0 then return the full physical<br>
            register<br>
                 assigned to the<br>
                 +/// virtual register ignoring subregs.  If we aren't<br>
            tracking<br>
                 sub-reg liveness<br>
                 +/// then we need to use this to be more conservative<br>
            with clobbers<br>
                 by killing<br>
                 +/// all super reg and their sub reg COPYs as well.             This is to<br>
                 prevent COPY<br>
                 +/// forwarding in cases like the following:<br>
                 +///<br>
                 +///    %vreg2 = COPY %vreg1:sub1<br>
                 +///    %vreg3 = COPY %vreg1:sub0<br>
                 +///    ...    = OP1 %vreg2<br>
                 +///    ...    = OP2 %vreg3<br>
                 +///<br>
                 +/// After forward %vreg2 (assuming this is the last<br>
            use of %vreg1) and<br>
                 +/// VirtRegRewriter adding kill markers we have:<br>
                 +///<br>
                 +///    %vreg3 = COPY %vreg1:sub0<br>
                 +///    ...    = OP1 %vreg1:sub1<kill><br>
                 +///    ...    = OP2 %vreg3<br>
                 +///<br>
                 +/// If %vreg3 is assigned to a sub-reg of %vreg1, then<br>
            after<br>
                 rewriting we have:<br>
                 +///<br>
                 +///    ...     = OP1 R0:sub1, R0<imp-use,kill><br>
                 +///    ...     = OP2 R0:sub0<br>
                 +///<br>
                 +/// and the use of R0 by OP2 will not have a valid<br>
            definition.<br>
                 +unsigned MachineCopyPropagation::getPhy<wbr>sReg(unsigned<br>
            Reg, unsigned<br>
                 SubReg) {<br>
                 +<br>
                 +  // Physical registers cannot have subregs.<br>
                 +  if (!TargetRegisterInfo::isVirtua<wbr>lRegister(Reg))<br>
                 +    return Reg;<br>
                 +<br>
                 +  assert(PreRegRewrite && "Unexpected virtual register<br>
            encountered");<br>
                 +  Reg = VRM->getPhys(Reg);<br>
                 +  if (SubReg && !NoSubRegLiveness)<br>
                 +    Reg = TRI->getSubReg(Reg, SubReg);<br>
                 +  return Reg;<br>
                 +}<br>
                 +<br>
                   /// Remove instruction \p Copy if there exists a<br>
            previous copy<br>
                 that copies the<br>
                   /// register \p Src to the register \p Def; This may<br>
            happen<br>
                 indirectly by<br>
                   /// copying the super registers.<br>
                 @@ -190,6 +360,325 @@ bool<br>
            MachineCopyPropagation::eraseI<wbr>fRedu<br>
                     return true;<br>
                   }<br>
<br>
                 +<br>
                 +/// Decide whether we should forward the destination<br>
            of \param Copy<br>
                 to its use<br>
                 +/// in \param UseI based on the register class of the Copy<br>
                 operands.  Same-class<br>
                 +/// COPYs are always accepted by this function, but<br>
            cross-class<br>
                 COPYs are only<br>
                 +/// accepted if they are forwarded to another COPY<br>
            with the operand<br>
                 register<br>
                 +/// classes reversed.  For example:<br>
                 +///<br>
                 +///   RegClassA = COPY RegClassB  // Copy parameter<br>
                 +///   ...<br>
                 +///   RegClassB = COPY RegClassA  // UseI parameter<br>
                 +///<br>
                 +/// which after forwarding becomes<br>
                 +///<br>
                 +///   RegClassA = COPY RegClassB<br>
                 +///   ...<br>
                 +///   RegClassB = COPY RegClassB<br>
                 +///<br>
                 +/// so we have reduced the number of cross-class COPYs<br>
            and potentially<br>
                 +/// introduced a no COPY that can be removed.<br>
                 +bool MachineCopyPropagation::isForw<wbr>ardableRegClassCopy(<br>
                 +    const MachineInstr &Copy, const MachineInstr &UseI) {<br>
                 +  auto isCross = [&](const MachineOperand &Dst, const<br>
                 MachineOperand &Src) {<br>
                 +    unsigned DstReg = Dst.getReg();<br>
                 +    unsigned SrcPhysReg = getPhysReg(Src);<br>
                 +    const TargetRegisterClass *DstRC;<br>
                 +    if (TargetRegisterInfo::isVirtual<wbr>Register(DstReg)) {<br>
                 +      DstRC = MRI->getRegClass(DstReg);<br>
                 +      unsigned DstSubReg = Dst.getSubReg();<br>
                 +      if (DstSubReg)<br>
                 +        SrcPhysReg = TRI->getMatchingSuperReg(SrcPh<wbr>ysReg,<br>
                 DstSubReg, DstRC);<br>
                 +    } else<br>
                 +      DstRC = TRI->getMinimalPhysRegClass(Ds<wbr>tReg);<br>
                 +<br>
                 +    return !DstRC->contains(SrcPhysReg);<br>
                 +  };<br>
                 +<br>
                 +  const MachineOperand &CopyDst = Copy.getOperand(0);<br>
                 +  const MachineOperand &CopySrc = Copy.getOperand(1);<br>
                 +<br>
                 +  if (!isCross(CopyDst, CopySrc))<br>
                 +    return true;<br>
                 +<br>
                 +  if (!UseI.isCopy())<br>
                 +    return false;<br>
                 +<br>
                 +  assert(getFullPhysReg(UseI.get<wbr>Operand(1)) ==<br>
                 getFullPhysReg(CopyDst));<br>
                 +  return !isCross(UseI.getOperand(0), CopySrc);<br>
                 +}<br>
                 +<br>
                 +/// Check that the subregs on the copy source operand<br>
            (\p CopySrc)<br>
                 and the use<br>
                 +/// operand to be forwarded to (\p MOUse) are<br>
            compatible with doing the<br>
                 +/// forwarding.  Also computes the new register and<br>
            subregister to<br>
                 be used in<br>
                 +/// the forwarded-to instruction.<br>
                 +std::tuple<unsigned, unsigned, bool><br>
                 MachineCopyPropagation::checkU<wbr>seSubReg(<br>
                 +    const MachineOperand &CopySrc, const<br>
            MachineOperand &MOUse) {<br>
                 +  unsigned NewUseReg = CopySrc.getReg();<br>
                 +  unsigned NewUseSubReg;<br>
                 +<br>
                 +  if (TargetRegisterInfo::isPhysica<wbr>lRegister(NewUseReg)) {<br>
                 +    // If MOUse is a virtual reg, we need to apply it<br>
            to the new<br>
                 physical reg<br>
                 +    // we're going to replace it with.<br>
                 +    if (MOUse.getSubReg())<br>
                 +      NewUseReg = TRI->getSubReg(NewUseReg,<br>
            MOUse.getSubReg());<br>
                 +    // If the original use subreg isn't valid on the<br>
            new src reg,<br>
                 we can't<br>
                 +    // forward it here.<br>
                 +    if (!NewUseReg)<br>
                 +      return std::make_tuple(0, 0, false);<br>
                 +    NewUseSubReg = 0;<br>
                 +  } else {<br>
                 +    // %v1 = COPY %v2:sub1<br>
                 +    //    USE %v1:sub2<br>
                 +    // The new use is %v2:sub1:sub2<br>
                 +    NewUseSubReg =<br>
                 +        TRI->composeSubRegIndices(Copy<wbr>Src.getSubReg(),<br>
                 MOUse.getSubReg());<br>
                 +    // Check that NewUseSubReg is valid on NewUseReg<br>
                 +    if (NewUseSubReg &&<br>
                 +                   !TRI->getSubClassWithSubReg(M<wbr>RI->getRegClass(NewUseReg),<br>
                 NewUseSubReg))<br>
                 +      return std::make_tuple(0, 0, false);<br>
                 +  }<br>
                 +<br>
                 +  return std::make_tuple(NewUseReg, NewUseSubReg, true);<br>
                 +}<br>
                 +<br>
                 +/// Check that \p MI does not have implicit uses that<br>
            overlap with<br>
                 it's \p Use<br>
                 +/// operand (the register being replaced), since these<br>
            can sometimes be<br>
                 +/// implicitly tied to other operands.  For example,<br>
            on AMDGPU:<br>
                 +///<br>
                 +/// V_MOVRELS_B32_e32 %VGPR2, %M0<imp-use>,<br>
            %EXEC<imp-use>,<br>
                 %VGPR2_VGPR3_VGPR4_VGPR5<imp-u<wbr>se><br>
                 +///<br>
                 +/// the %VGPR2 is implicitly tied to the larger reg<br>
            operand, but we<br>
                 have no<br>
                 +/// way of knowing we need to update the latter when<br>
            updating the<br>
                 former.<br>
                 +bool MachineCopyPropagation::hasImp<wbr>licitOverlap(const<br>
            MachineInstr &MI,<br>
                 +                                                const<br>
                 MachineOperand &Use) {<br>
                 +  if<br>
            (!TargetRegisterInfo::isPhysic<wbr>alRegister(Use.getReg()))<br>
                 +    return false;<br>
                 +<br>
                 +  for (const MachineOperand &MIUse : MI.uses())<br>
                 +    if (&MIUse != &Use && MIUse.isReg() &&<br>
            MIUse.isImplicit() &&<br>
                 +        TRI->regsOverlap(Use.getReg(), MIUse.getReg()))<br>
                 +      return true;<br>
                 +<br>
                 +  return false;<br>
                 +}<br>
                 +<br>
                 +/// Narrow the register class of the forwarded vreg so<br>
            it matches any<br>
                 +/// instruction constraints.  \p MI is the instruction<br>
            being<br>
                 forwarded to. \p<br>
                 +/// MOUse is the operand being replaced in \p MI<br>
            (which hasn't yet<br>
                 been updated<br>
                 +/// at the time this function is called).  \p<br>
            NewUseReg and \p<br>
                 NewUseSubReg are<br>
                 +/// what the \p MOUse will be changed to after forwarding.<br>
                 +///<br>
                 +/// If we are forwarding<br>
                 +///    A:RCA = COPY B:RCB<br>
                 +/// into<br>
                 +///    ... = OP A:RCA<br>
                 +///<br>
                 +/// then we need to narrow the register class of B so<br>
            that it is a<br>
                 subclass<br>
                 +/// of RCA so that it meets the instruction register<br>
            class constraints.<br>
                 +void MachineCopyPropagation::narrow<wbr>RegClass(const<br>
            MachineInstr &MI,<br>
                 +                                            const<br>
            MachineOperand<br>
                 &MOUse,<br>
                 +                                            unsigned<br>
            NewUseReg,<br>
                 +                                            unsigned<br>
            NewUseSubReg) {<br>
                 +  if (!TargetRegisterInfo::isVirtua<wbr>lRegister(NewUseReg))<br>
                 +    return;<br>
                 +<br>
                 +  // Make sure the virtual reg class allows the subreg.<br>
                 +  if (NewUseSubReg) {<br>
                 +    const TargetRegisterClass *CurUseRC =<br>
            MRI->getRegClass(NewUseReg);<br>
                 +    const TargetRegisterClass *NewUseRC =<br>
                 +        TRI->getSubClassWithSubReg(Cur<wbr>UseRC,<br>
            NewUseSubReg);<br>
                 +    if (CurUseRC != NewUseRC) {<br>
                 +      DEBUG(dbgs() << "MCP: Setting regclass of " <<<br>
                 PrintReg(NewUseReg, TRI)<br>
                 +                   << " to " <<<br>
            TRI->getRegClassName(NewUseRC) <<<br>
                 "\n");<br>
                 +      MRI->setRegClass(NewUseReg, NewUseRC);<br>
                 +    }<br>
                 +  }<br>
                 +<br>
                 +  unsigned MOUseOpNo = &MOUse - &MI.getOperand(0);<br>
                 +  const TargetRegisterClass *InstRC =<br>
                 +      TII->getRegClass(MI.getDesc(), MOUseOpNo, TRI, *MF);<br>
                 +  if (InstRC) {<br>
                 +    const TargetRegisterClass *CurUseRC =<br>
            MRI->getRegClass(NewUseReg);<br>
                 +    if (NewUseSubReg)<br>
                 +      InstRC = TRI->getMatchingSuperRegClass(<wbr>CurUseRC,<br>
            InstRC,<br>
                 NewUseSubReg);<br>
                 +    if (!InstRC->hasSubClassEq(CurUse<wbr>RC)) {<br>
                 +      const TargetRegisterClass *NewUseRC =<br>
                 +          TRI->getCommonSubClass(InstRC, CurUseRC);<br>
                 +      DEBUG(dbgs() << "MCP: Setting regclass of " <<<br>
                 PrintReg(NewUseReg, TRI)<br>
                 +                   << " to " <<<br>
            TRI->getRegClassName(NewUseRC) <<<br>
                 "\n");<br>
                 +      MRI->setRegClass(NewUseReg, NewUseRC);<br>
                 +    }<br>
                 +  }<br>
                 +}<br>
                 +<br>
                 +/// Update the LiveInterval information to reflect the<br>
            destination<br>
                 of \p Copy<br>
                 +/// being forwarded to a use in \p UseMI.  \p<br>
            OrigUseReg is the<br>
                 register being<br>
                 +/// forwarded through. It should be the destination<br>
            register of \p<br>
                 Copy and has<br>
                 +/// already been replaced in \p UseMI at the point<br>
            this function is<br>
                 called.  \p<br>
                 +/// NewUseReg and \p NewUseSubReg are the register and<br>
            subregister<br>
                 being<br>
                 +/// forwarded.  They should be the source register of<br>
            the \p Copy<br>
                 and should be</blockquote>
</blockquote></div><br></div>