Use address-taken to disambiguate global variable and indirect memops.
authorShuxin Yang <shuxin.llvm@gmail.com>
Wed, 23 Oct 2013 17:28:19 +0000 (17:28 +0000)
committerShuxin Yang <shuxin.llvm@gmail.com>
Wed, 23 Oct 2013 17:28:19 +0000 (17:28 +0000)
 Major steps include:
 1). introduces a not-addr-taken bit-field in GlobalVariable
 2). GlobalOpt pass sets "not-address-taken" if it proves a global varirable
    dosen't have its address taken.
 3). AA use this info for disambiguation.

llvm-svn: 193251

18 files changed:
llvm/docs/LangRef.rst
llvm/include/llvm/IR/GlobalVariable.h
llvm/lib/Analysis/BasicAliasAnalysis.cpp
llvm/lib/AsmParser/LLLexer.cpp
llvm/lib/AsmParser/LLParser.cpp
llvm/lib/AsmParser/LLToken.h
llvm/lib/Bitcode/Reader/BitcodeReader.cpp
llvm/lib/Bitcode/Writer/BitcodeWriter.cpp
llvm/lib/IR/AsmWriter.cpp
llvm/lib/IR/Globals.cpp
llvm/lib/Transforms/IPO/GlobalOpt.cpp
llvm/test/Analysis/BasicAA/noaddrtaken.ll [new file with mode: 0644]
llvm/test/Transforms/GlobalOpt/2009-03-07-PromotePtrToBool.ll
llvm/test/Transforms/GlobalOpt/2009-11-16-MallocSingleStoreToGlobalVar.ll
llvm/test/Transforms/GlobalOpt/atomic.ll
llvm/test/Transforms/GlobalOpt/globalsra-unknown-index.ll
llvm/test/Transforms/GlobalOpt/integer-bool.ll
llvm/test/Transforms/GlobalOpt/unnamed-addr.ll

index b75c6b1..1e2016b 100644 (file)
@@ -511,6 +511,9 @@ module, including those with external linkage or appearing in
 ``@llvm.used``. This assumption may be suppressed by marking the
 variable with ``externally_initialized``.
 
+If a global variable dose not have its address taken, it will be optionally
+flagged ``notaddrtaken``.
+
 An explicit alignment may be specified for a global, which must be a
 power of 2. If not present, or if the alignment is set to zero, the
 alignment of the global is set by the target to whatever it feels
index bfed507..a5ab97d 100644 (file)
@@ -48,6 +48,7 @@ class GlobalVariable : public GlobalValue, public ilist_node<GlobalVariable> {
                                                // can change from its initial
                                                // value before global
                                                // initializers are run?
+  bool notAddrTaken : 1;                       // Dose not have address taken.
 
 public:
   // allocate space for exactly one operand
@@ -174,6 +175,9 @@ public:
     isExternallyInitializedConstant = Val;
   }
 
+  void setAddressMaybeTaken(bool Val) { notAddrTaken = !Val; }
+  bool AddressMaybeTaken(void) const { return !notAddrTaken; }
+
   /// copyAttributesFrom - copy all additional attributes (those not needed to
   /// create a GlobalVariable) from the GlobalVariable Src to this one.
   void copyAttributesFrom(const GlobalValue *Src);
index bf92969..4e423a7 100644 (file)
@@ -1238,6 +1238,17 @@ BasicAliasAnalysis::aliasCheck(const Value *V1, uint64_t V1Size,
       return NoAlias;
     if (isEscapeSource(O2) && isNonEscapingLocalObject(O1))
       return NoAlias;
+
+    // If one object is a global variable without address taken, the other one
+    // is a different object, they will not alias because the global variable
+    // in question cannot be indirectly accessed.
+    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(O1))
+      if (!GV->AddressMaybeTaken())
+        return NoAlias;
+
+    if (const GlobalVariable *GV = dyn_cast<GlobalVariable>(O2))
+      if (!GV->AddressMaybeTaken())
+        return NoAlias;
   }
 
   // If the size of one access is larger than the entire object on the other
index 99bff45..6d643b6 100644 (file)
@@ -504,6 +504,7 @@ lltok::Kind LLLexer::LexIdentifier() {
   KEYWORD(zeroinitializer);
   KEYWORD(undef);
   KEYWORD(null);
+  KEYWORD(notaddrtaken);
   KEYWORD(to);
   KEYWORD(tail);
   KEYWORD(target);
index 74c0ea4..9b5fb27 100644 (file)
@@ -704,7 +704,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
                            unsigned Linkage, bool HasLinkage,
                            unsigned Visibility) {
   unsigned AddrSpace;
-  bool IsConstant, UnnamedAddr, IsExternallyInitialized;
+  bool IsConstant, UnnamedAddr, IsExternallyInitialized, notAddrTaken;
   GlobalVariable::ThreadLocalMode TLM;
   LocTy UnnamedAddrLoc;
   LocTy IsExternallyInitializedLoc;
@@ -719,6 +719,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
                          IsExternallyInitialized,
                          &IsExternallyInitializedLoc) ||
       ParseGlobalType(IsConstant) ||
+      ParseOptionalToken(lltok::kw_notaddrtaken, notAddrTaken) ||
       ParseType(Ty, TyLoc))
     return true;
 
@@ -776,6 +777,7 @@ bool LLParser::ParseGlobal(const std::string &Name, LocTy NameLoc,
   GV->setLinkage((GlobalValue::LinkageTypes)Linkage);
   GV->setVisibility((GlobalValue::VisibilityTypes)Visibility);
   GV->setExternallyInitialized(IsExternallyInitialized);
+  GV->setAddressMaybeTaken(!notAddrTaken);
   GV->setThreadLocalMode(TLM);
   GV->setUnnamedAddr(UnnamedAddr);
 
index e1382fd..7832e81 100644 (file)
@@ -51,6 +51,7 @@ namespace lltok {
     kw_localdynamic, kw_initialexec, kw_localexec,
     kw_zeroinitializer,
     kw_undef, kw_null,
+    kw_notaddrtaken,
     kw_to,
     kw_tail,
     kw_target,
index e408cd1..3fca4ab 100644 (file)
@@ -1848,6 +1848,9 @@ bool BitcodeReader::ParseModule(bool Resume) {
         new GlobalVariable(*TheModule, Ty, isConstant, Linkage, 0, "", 0,
                            TLM, AddressSpace, ExternallyInitialized);
       NewGV->setAlignment(Alignment);
+      if (Record.size() > 10)
+        NewGV->setAddressMaybeTaken(Record[10]);
+
       if (!Section.empty())
         NewGV->setSection(Section);
       NewGV->setVisibility(Visibility);
index b082ba6..4f631b9 100644 (file)
@@ -616,11 +616,13 @@ static void WriteModuleInfo(const Module *M, const ValueEnumerator &VE,
     Vals.push_back(GV->hasSection() ? SectionMap[GV->getSection()] : 0);
     if (GV->isThreadLocal() ||
         GV->getVisibility() != GlobalValue::DefaultVisibility ||
-        GV->hasUnnamedAddr() || GV->isExternallyInitialized()) {
+        GV->hasUnnamedAddr() || GV->isExternallyInitialized() ||
+        !GV->AddressMaybeTaken()) {
       Vals.push_back(getEncodedVisibility(GV));
       Vals.push_back(getEncodedThreadLocalMode(GV));
       Vals.push_back(GV->hasUnnamedAddr());
       Vals.push_back(GV->isExternallyInitialized());
+      Vals.push_back(GV->AddressMaybeTaken());
     } else {
       AbbrevToUse = SimpleGVarAbbrev;
     }
index 6e3b853..dc337c1 100644 (file)
@@ -1459,6 +1459,7 @@ void AssemblyWriter::printGlobal(const GlobalVariable *GV) {
   if (GV->hasUnnamedAddr()) Out << "unnamed_addr ";
   if (GV->isExternallyInitialized()) Out << "externally_initialized ";
   Out << (GV->isConstant() ? "constant " : "global ");
+  if (!GV->AddressMaybeTaken()) Out << "notaddrtaken ";
   TypePrinter.print(GV->getType()->getElementType(), Out);
 
   if (GV->hasInitializer()) {
index da3b02a..8c28ec1 100644 (file)
@@ -99,6 +99,7 @@ GlobalVariable::GlobalVariable(Type *Ty, bool constant, LinkageTypes Link,
   }
 
   LeakDetector::addGarbageObject(this);
+  setAddressMaybeTaken(true);
 }
 
 GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
@@ -125,6 +126,7 @@ GlobalVariable::GlobalVariable(Module &M, Type *Ty, bool constant,
     Before->getParent()->getGlobalList().insert(Before, this);
   else
     M.getGlobalList().push_back(this);
+  setAddressMaybeTaken(true);
 }
 
 void GlobalVariable::setParent(Module *parent) {
@@ -185,6 +187,7 @@ void GlobalVariable::copyAttributesFrom(const GlobalValue *Src) {
   GlobalValue::copyAttributesFrom(Src);
   const GlobalVariable *SrcVar = cast<GlobalVariable>(Src);
   setThreadLocal(SrcVar->isThreadLocal());
+  setAddressMaybeTaken(SrcVar->AddressMaybeTaken());
 }
 
 
index 82a59ed..a259b4d 100644 (file)
@@ -1723,6 +1723,7 @@ bool GlobalOpt::ProcessGlobal(GlobalVariable *GV,
   if (GlobalStatus::analyzeGlobal(GV, GS))
     return false;
 
+  GV->setAddressMaybeTaken(false);
   if (!GS.IsCompared && !GV->hasUnnamedAddr()) {
     GV->setUnnamedAddr(true);
     NumUnnamed++;
diff --git a/llvm/test/Analysis/BasicAA/noaddrtaken.ll b/llvm/test/Analysis/BasicAA/noaddrtaken.ll
new file mode 100644 (file)
index 0000000..14aa45b
--- /dev/null
@@ -0,0 +1,29 @@
+; RUN: opt < %s -basicaa -aa-eval -print-all-alias-modref-info 2>&1 | FileCheck %s
+
+; ModuleID = 'b.c'
+target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-s0:64:64-f80:128:128-n8:16:32:64-S128"
+target triple = "x86_64-apple-macosx10.8.0"
+
+; CHECK: NoAlias:   i32* %p, i32* @xyz
+
+;@xyz = global i32 12, align 4
+@xyz = internal unnamed_addr global notaddrtaken i32 12, align 4
+
+; Function Attrs: nounwind ssp uwtable
+define i32 @foo(i32* nocapture %p, i32* nocapture %q) #0 {
+entry:
+  %0 = load i32* @xyz, align 4, !tbaa !0
+  %inc = add nsw i32 %0, 1
+  store i32 %inc, i32* @xyz, align 4, !tbaa !0
+  store i32 1, i32* %p, align 4, !tbaa !0
+  %1 = load i32* @xyz, align 4, !tbaa !0
+  store i32 %1, i32* %q, align 4, !tbaa !0
+  ret i32 undef
+}
+
+attributes #0 = { nounwind ssp uwtable "less-precise-fpmad"="false" "no-frame-pointer-elim"="true" "no-frame-pointer-elim-non-leaf" "no-infs-fp-math"="false" "no-nans-fp-math"="false" "stack-protector-buffer-size"="8" "unsafe-fp-math"="false" "use-soft-float"="false" }
+
+!0 = metadata !{metadata !1, metadata !1, i64 0}
+!1 = metadata !{metadata !"int", metadata !2, i64 0}
+!2 = metadata !{metadata !"omnipotent char", metadata !3, i64 0}
+!3 = metadata !{metadata !"Simple C/C++ TBAA"}
index 059af1c..87f2889 100644 (file)
@@ -1,4 +1,4 @@
-; RUN: opt < %s -globalopt -S | grep "@X = internal unnamed_addr global i32"
+; RUN: opt < %s -globalopt -S | grep "@X = internal unnamed_addr global notaddrtaken i32"
 target datalayout = "e-p:32:32:32-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:32:64-f32:32:32-f64:32:64-v64:64:64-v128:128:128-a0:0:64-f80:128:128"
 target triple = "i386-apple-darwin7"
 @X = internal global i32* null         ; <i32**> [#uses=2]
index b73f62b..fd7b4dd 100644 (file)
@@ -8,7 +8,7 @@ target datalayout = "e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f3
 target triple = "x86_64-apple-darwin10.0"
 
 @TOP = internal global i64* null                    ; <i64**> [#uses=2]
-; CHECK: @TOP = internal unnamed_addr global i64* null
+; CHECK: @TOP = internal unnamed_addr global notaddrtaken i64* null
 @channelColumns = internal global i64 0             ; <i64*> [#uses=2]
 
 ; Derived from @DescribeChannel() in yacr2
index ac05bfd..d0fb970 100644 (file)
@@ -3,8 +3,8 @@
 @GV1 = internal global i64 1
 @GV2 = internal global i32 0
 
-; CHECK: @GV1 = internal unnamed_addr constant i64 1
-; CHECK: @GV2 = internal unnamed_addr global i32 0
+; CHECK: @GV1 = internal unnamed_addr constant notaddrtaken i64 1
+; CHECK: @GV2 = internal unnamed_addr global notaddrtaken i32 0
 
 define void @test1() {
 entry:
index cc655e9..a854d94 100644 (file)
@@ -1,5 +1,5 @@
 ; RUN: opt < %s -globalopt -S > %t
-; RUN: grep "@Y = internal unnamed_addr global \[3 x [%]struct.X\] zeroinitializer" %t
+; RUN: grep "@Y = internal unnamed_addr global notaddrtaken \[3 x [%]struct.X\] zeroinitializer" %t
 ; RUN: grep load %t | count 6
 ; RUN: grep "add i32 [%]a, [%]b" %t | count 3
 
index abf5fdd..a75614e 100644 (file)
@@ -4,7 +4,7 @@
 @G = internal addrspace(1) global i32 0
 ; CHECK: @G
 ; CHECK: addrspace(1)
-; CHECK: global i1 false
+; CHECK: global notaddrtaken i1 false
 
 define void @set1() {
   store i32 0, i32 addrspace(1)* @G
index 2ca91e5..7b049ec 100644 (file)
@@ -6,10 +6,10 @@
 @d = internal constant [4 x i8] c"foo\00", align 1
 @e = linkonce_odr global i32 0
 
-; CHECK: @a = internal global i32 0, align 4
+; CHECK: @a = internal global notaddrtaken i32 0, align 4
 ; CHECK: @b = internal global i32 0, align 4
-; CHECK: @c = internal unnamed_addr global i32 0, align 4
-; CHECK: @d = internal unnamed_addr constant [4 x i8] c"foo\00", align 1
+; CHECK: @c = internal unnamed_addr global notaddrtaken i32 0, align 4
+; CHECK: @d = internal unnamed_addr constant notaddrtaken [4 x i8] c"foo\00", align 1
 ; CHECK: @e = linkonce_odr global i32 0
 
 define i32 @get_e() {