[PATCH] D61947: Merge of Global Constants not happening on Aarch64

Ramakota Reddy via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Wed May 15 07:37:13 PDT 2019


ramred01 created this revision.
ramred01 added reviewers: efriedma, Jiangning, john.brawn, ab.
Herald added subscribers: kristof.beyls, javed.absar.

Merge of global constants does not happen on Aarch64 even when the constants are used in successive instructions. It generates two separate labels for the two constants and hence materializes the two label addresses separately before loading the two constants.  Instead if it were to merg the two constants and create a common label, it would have meant loading the label address once in a base register and then loading the constants using an offset from that label.

The reason phenomenon is seen on Aarch64 but not on arm-none-eabi is because merging of external globals is not enabled by default for the GlobalMerge Pass on Aarch64, when it should ideally be.  It is disabled only for Mach-O systems where we emit the .subsections_by_symbols directive and it is not safe to merge external globals.  This patch enables the MergeExternalBydefault for the GlobalMerge pass.


https://reviews.llvm.org/D61947

Files:
  lib/CodeGen/GlobalMerge.cpp
  lib/Target/AArch64/AArch64TargetMachine.cpp
  test/CodeGen/AArch64/global_merge_aarc64_ac6.ll


Index: test/CodeGen/AArch64/global_merge_aarc64_ac6.ll
===================================================================
--- /dev/null
+++ test/CodeGen/AArch64/global_merge_aarc64_ac6.ll
@@ -0,0 +1,35 @@
+;RUN: llc -O3 %s -o - -verify-machineinstrs | FileCheck %s
+
+target datalayout = "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
+target triple = "aarch64-arm-none-eabi"
+
+ at global0 = dso_local local_unnamed_addr global i32 0, align 4
+ at global1 = dso_local local_unnamed_addr global i32 0, align 4
+
+; Function Attrs: minsize norecurse nounwind optsize readonly
+
+;CHECK-LABEL: @func
+;CHECK: adrp x8, .L_MergedGlobals 
+;CHECK: add x8, x8, :lo12:.L_MergedGlobals
+;CHECK-NEXT: ldp
+;CHECK-NEXT: add
+;CHECK-NEXT: ret
+define dso_local i32 @func() local_unnamed_addr #0 {
+entry:
+  %0 = load i32, i32* @global0, align 4, !tbaa !2
+  %1 = load i32, i32* @global1, align 4, !tbaa !2
+  %add = add nsw i32 %1, %0
+  ret i32 %add
+}
+
+attributes #0 = { minsize norecurse nounwind optsize readonly "correctly-rounded-divide-sqrt-fp-math"="false" "disable-tail-calls"="false" "less-precise-fpmad"="false" "min-legal-vector-width"="0" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-jump-tables"="false" "no-nans-fp-math"="false" "no-signed-zeros-fp-math"="false" "no-trapping-math"="false" "stack-protector-buffer-size"="8" "target-cpu"="cortex-a53" "target-features"="+aes,+crc,+crypto,+fp-armv8,+neon,+sha2" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!llvm.module.flags = !{!0}
+!llvm.ident = !{!1}
+
+!0 = !{i32 1, !"wchar_size", i32 4}
+!1 = !{!"clang version 9.0.0 (https://git.llvm.org/git/clang.git/ 7a6d690bb52df60e979a7c7f9d03a774009bb443) (https://git.llvm.org/git/llvm.git/ 71abe189dddb95b0d5782e0866058b9a92ff2402)"}
+!2 = !{!3, !3, i64 0}
+!3 = !{!"int", !4, i64 0}
+!4 = !{!"omnipotent char", !5, i64 0}
+!5 = !{!"Simple C/C++ TBAA"}
Index: lib/Target/AArch64/AArch64TargetMachine.cpp
===================================================================
--- lib/Target/AArch64/AArch64TargetMachine.cpp
+++ lib/Target/AArch64/AArch64TargetMachine.cpp
@@ -461,7 +461,14 @@
       EnableGlobalMerge == cl::BOU_TRUE) {
     bool OnlyOptimizeForSize = (TM->getOptLevel() < CodeGenOpt::Aggressive) &&
                                (EnableGlobalMerge == cl::BOU_UNSET);
-    addPass(createGlobalMergePass(TM, 4095, OnlyOptimizeForSize));
+    
+    // Merging of extern globals is enabled by default on non-Mach-O as we
+    // expect it to be generally either beneficial or harmless. On Mach-O it
+    // is disabled as we emit the .subsections_via_symbols directive which
+    // means that merging extern globals is not safe.
+    bool MergeExternalByDefault = !TM->getTargetTriple().isOSBinFormatMachO();
+    addPass(createGlobalMergePass(TM, 4095, OnlyOptimizeForSize, 
+                                  MergeExternalByDefault));
   }
 
   return false;
Index: lib/CodeGen/GlobalMerge.cpp
===================================================================
--- lib/CodeGen/GlobalMerge.cpp
+++ lib/CodeGen/GlobalMerge.cpp
@@ -615,7 +615,7 @@
     // It's not safe to merge globals that may be preempted
     if (TM && !TM->shouldAssumeDSOLocal(M, &GV))
       continue;
-
+    
     if (!(MergeExternalGlobals && GV.hasExternalLinkage()) &&
         !GV.hasInternalLinkage())
       continue;


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D61947.199605.patch
Type: text/x-patch
Size: 3377 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20190515/d5298a6a/attachment.bin>


More information about the llvm-commits mailing list