[llvm] r311038 - [MachineCopyPropagation] Extend pass to do COPY source forwarding

Geoff Berry via llvm-commits llvm-commits at lists.llvm.org
Thu Aug 24 18:27:41 PDT 2017


Never mind, I believe I've tracked down at least one mis-compile of 
llvm-symbolizer using an emulator running Android w/ SDK version 24

On 8/24/2017 12:35 PM, Geoff Berry via llvm-commits wrote:
> I let it run all night.  Definitely hung.  I changed my cmake setting so 
> that lit only runs one test at a time (-j1) and the first test that 
> hangs is interception_test.cc, which is a very small test.
> 
> I did have to change the Android API version from 24 to 23 in the script 
> since I don't have a device with that version of Android installed on it 
> handy.  Perhaps that is the cause of the hang?
> 
> I'm trying to get my hands on a newer Android version device, but in the 
> mean time would you be able to do a run at revision 311141 (which 
> includes my original change) with -DLLVM_LIT_ARGS="-vv -j1" so we can 
> determine exactly which lit test is hanging?
> 
> On 8/23/2017 5:54 PM, Vitaly Buka wrote:
>> 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 
>> <mailto: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.tm
>>     <http://local_quarantine_size_kb.cc.tm>p
>>     /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 
>>
>>         
>> <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>
>>         <mailto: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>
>>              <mailto: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> 
>>
>>         
>> <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>>
>>                      <mailto: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-project?rev=311038&view=rev
>>         <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-project?rev=311038&view=rev>
>>         <http://llvm.org/viewvc/llvm-project?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>>
>>                           <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/AArch64/aarch64-fold-lslfast.ll
>>            llvm/trunk/test/CodeGen/AArch64/arm64-AdvSIMD-Scalar.ll
>>            llvm/trunk/test/CodeGen/AArch64/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/AArch64/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/AMDGPU/call-argument-types.ll
>>            llvm/trunk/test/CodeGen/AMDGPU/call-preserved-registers.ll
>>            llvm/trunk/test/CodeGen/AMDGPU/callee-special-input-sgprs.ll
>>            llvm/trunk/test/CodeGen/AMDGPU/callee-special-input-vgprs.ll
>>           llvm/trunk/test/CodeGen/AMDGPU/mubuf-offset-private.ll
>>           llvm/trunk/test/CodeGen/AMDGPU/multilevel-break.ll
>>            llvm/trunk/test/CodeGen/AMDGPU/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/PowerPC/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/statepoint-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/vector-shift-ashr-128.ll
>>           llvm/trunk/test/CodeGen/X86/vector-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/x86-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-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-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-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>>> 
>>
>>         
>> ============================================================================== 
>>
>>                           --- 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-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-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-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>>> 
>>
>>         
>> ============================================================================== 
>>
>>                           --- 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
>>         initializeMachineCopyPropagationPass(PassRegistry&);
>>                           +void
>>         initializeMachineCopyPropagationPreRegRewritePass(PassRegistry&);
>>                             void
>>                      
>> initializeMachineDominanceFrontierPass(PassRegistry&);
>>                             void
>>         initializeMachineDominatorTreePass(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-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-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-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>>> 
>>
>>         
>> ============================================================================== 
>>
>>                           --- 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(PassRegistr
>>                               initializeMachineCSEPass(Registry);
>>                               initializeMachineCombinerPass(Registry);
>>         initializeMachineCopyPropagationPass(Registry);
>>                           +
>>         initializeMachineCopyPropagationPreRegRewritePass(Registry);
>>                               
>> initializeMachineDominatorTreePass(Registry);
>>         initializeMachineFunctionPrinterPassPass(Registry);
>>                               initializeMachineLICMPass(Registry);
>>
>>                           Modified:
>>         llvm/trunk/lib/CodeGen/MachineCopyPropagation.cpp
>>                           URL:
>>         
>> 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-project/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 
>>
>>         
>> <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-project/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> 
>>
>>         
>> <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-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) {
>>         
>> initializeMachineCopyPropagationPass(*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(MachineFunctionProperties::Property::NoPHIs)
>>                           +          
>>  .set(MachineFunctionProperties::Property::TracksLiveness);
>>                                   return MachineFunctionProperties().set(
>>         MachineFunctionProperties::Property::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) {
>>                           +          
>>  initializeMachineCopyPropagationPreRegRewritePass(*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(MachineCopyPropagationPreRegRewrite,
>>                           +                      "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(MachineCopyPropagationPreRegRewrite,
>>                           +                    "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(SrcPhysReg,
>>                           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(MRI->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::isVirtualRegister(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
>>
>>
> 

-- 
Geoff Berry
Employee of Qualcomm Datacenter Technologies, Inc.
  Qualcomm Datacenter Technologies, Inc. as an affiliate of Qualcomm 
Technologies, Inc.  Qualcomm Technologies, Inc. is a member of the Code 
Aurora Forum, a Linux Foundation Collaborative Project.


More information about the llvm-commits mailing list