Use MDBuilder to build metadata.

Change-Id: I7e6872bf46c5e064a8cc936edfd18566610d80d5
diff --git a/build/Android.libart-compiler-llvm.mk b/build/Android.libart-compiler-llvm.mk
index 894fb542..34de2fa 100644
--- a/build/Android.libart-compiler-llvm.mk
+++ b/build/Android.libart-compiler-llvm.mk
@@ -27,13 +27,13 @@
 	src/compiler_llvm/inferred_reg_category_map.cc \
 	src/compiler_llvm/ir_builder.cc \
 	src/compiler_llvm/jni_compiler.cc \
+	src/compiler_llvm/md_builder.cc \
 	src/compiler_llvm/runtime_support_builder.cc \
 	src/compiler_llvm/runtime_support_builder_arm.cc \
 	src/compiler_llvm/runtime_support_builder_thumb2.cc \
 	src/compiler_llvm/runtime_support_builder_x86.cc \
 	src/compiler_llvm/runtime_support_llvm.cc \
-	src/compiler_llvm/stub_compiler.cc \
-	src/compiler_llvm/tbaa_info.cc
+	src/compiler_llvm/stub_compiler.cc
 
 ifeq ($(ART_USE_DEXLANG_FRONTEND),true)
   LIBART_COMPILER_LLVM_SRC_FILES += \
diff --git a/src/compiler_llvm/ir_builder.cc b/src/compiler_llvm/ir_builder.cc
index d93b588..8ee4f3e 100644
--- a/src/compiler_llvm/ir_builder.cc
+++ b/src/compiler_llvm/ir_builder.cc
@@ -19,8 +19,6 @@
 
 #include <llvm/Module.h>
 
-#include <algorithm>
-
 namespace art {
 namespace compiler_llvm {
 
@@ -30,7 +28,7 @@
 //----------------------------------------------------------------------------
 
 IRBuilder::IRBuilder(llvm::LLVMContext& context, llvm::Module& module)
-: LLVMIRBuilder(context), module_(&module), tbaa_(context) {
+: LLVMIRBuilder(context), module_(&module), mdb_(context) {
 
   // Get java object type from module
   llvm::Type* jobject_struct_type = module.getTypeByName("JavaObject");
@@ -46,22 +44,6 @@
   CHECK(art_frame_type_ != NULL);
 
   runtime_support_ = NULL;
-
-
-  // Pre-generate the MDNode for static branch prediction
-  llvm::Type* int32ty = llvm::Type::getInt32Ty(context);
-  llvm::MDString* branch_weights = llvm::MDString::get(context, "branch_weights");
-  llvm::Constant* likely = llvm::ConstantInt::get(int32ty, 64);
-  llvm::Constant* unlikely = llvm::ConstantInt::get(int32ty, 4);
-  llvm::Value *opts[] = {
-    branch_weights,
-    likely,
-    unlikely
-  };
-
-  expect_cond_[kLikely] = llvm::MDNode::get(context, opts);
-  std::swap(opts[1], opts[2]);
-  expect_cond_[kUnlikely] = llvm::MDNode::get(context, opts);
 }
 
 
diff --git a/src/compiler_llvm/ir_builder.h b/src/compiler_llvm/ir_builder.h
index f21cfaf..5df9831 100644
--- a/src/compiler_llvm/ir_builder.h
+++ b/src/compiler_llvm/ir_builder.h
@@ -18,9 +18,9 @@
 #define ART_SRC_COMPILER_LLVM_IR_BUILDER_H_
 
 #include "backend_types.h"
+#include "md_builder.h"
 #include "runtime_support_builder.h"
 #include "runtime_support_func.h"
-#include "tbaa_info.h"
 
 #include <llvm/Constants.h>
 #include <llvm/DerivedTypes.h>
@@ -72,29 +72,29 @@
 
   // TODO: After we design the non-special TBAA info, re-design the TBAA interface.
   llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty) {
-    return CreateLoad(ptr, tbaa_.GetSpecialType(special_ty));
+    return CreateLoad(ptr, mdb_.GetTBAASpecialType(special_ty));
   }
 
   llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr, TBAASpecialType special_ty) {
     DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
-    return CreateStore(val, ptr, tbaa_.GetSpecialType(special_ty));
+    return CreateStore(val, ptr, mdb_.GetTBAASpecialType(special_ty));
   }
 
   llvm::LoadInst* CreateLoad(llvm::Value* ptr, TBAASpecialType special_ty, JType j_ty) {
-    return CreateLoad(ptr, tbaa_.GetMemoryJType(special_ty, j_ty));
+    return CreateLoad(ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
   }
 
   llvm::StoreInst* CreateStore(llvm::Value* val, llvm::Value* ptr,
                                TBAASpecialType special_ty, JType j_ty) {
     DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
-    return CreateStore(val, ptr, tbaa_.GetMemoryJType(special_ty, j_ty));
+    return CreateStore(val, ptr, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
   }
 
   llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
                                        int64_t offset,
                                        llvm::Type* type,
                                        TBAASpecialType special_ty) {
-    return LoadFromObjectOffset(object_addr, offset, type, tbaa_.GetSpecialType(special_ty));
+    return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAASpecialType(special_ty));
   }
 
   void StoreToObjectOffset(llvm::Value* object_addr,
@@ -102,14 +102,14 @@
                            llvm::Value* new_value,
                            TBAASpecialType special_ty) {
     DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
-    StoreToObjectOffset(object_addr, offset, new_value, tbaa_.GetSpecialType(special_ty));
+    StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAASpecialType(special_ty));
   }
 
   llvm::LoadInst* LoadFromObjectOffset(llvm::Value* object_addr,
                                        int64_t offset,
                                        llvm::Type* type,
                                        TBAASpecialType special_ty, JType j_ty) {
-    return LoadFromObjectOffset(object_addr, offset, type, tbaa_.GetMemoryJType(special_ty, j_ty));
+    return LoadFromObjectOffset(object_addr, offset, type, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
   }
 
   void StoreToObjectOffset(llvm::Value* object_addr,
@@ -117,11 +117,11 @@
                            llvm::Value* new_value,
                            TBAASpecialType special_ty, JType j_ty) {
     DCHECK_NE(special_ty, kTBAAConstJObject) << "ConstJObject is read only!";
-    StoreToObjectOffset(object_addr, offset, new_value, tbaa_.GetMemoryJType(special_ty, j_ty));
+    StoreToObjectOffset(object_addr, offset, new_value, mdb_.GetTBAAMemoryJType(special_ty, j_ty));
   }
 
   void SetTBAA(llvm::Instruction* inst, TBAASpecialType special_ty) {
-    inst->setMetadata(llvm::LLVMContext::MD_tbaa, tbaa_.GetSpecialType(special_ty));
+    inst->setMetadata(llvm::LLVMContext::MD_tbaa, mdb_.GetTBAASpecialType(special_ty));
   }
 
 
@@ -135,10 +135,8 @@
                                  llvm::BasicBlock* true_bb,
                                  llvm::BasicBlock* false_bb,
                                  ExpectCond expect) {
-    DCHECK_LT(expect, MAX_EXPECT) << "MAX_EXPECT is not for branch weight";
-
-    llvm::BranchInst* branch_inst = LLVMIRBuilder::CreateCondBr(cond, true_bb, false_bb);
-    branch_inst->setMetadata(llvm::LLVMContext::MD_prof, expect_cond_[expect]);
+    llvm::BranchInst* branch_inst = CreateCondBr(cond, true_bb, false_bb);
+    branch_inst->setMetadata(llvm::LLVMContext::MD_prof, mdb_.GetBranchWeights(expect));
     return branch_inst;
   }
 
@@ -423,11 +421,9 @@
 
   llvm::StructType* art_frame_type_;
 
-  TBAAInfo tbaa_;
+  MDBuilder mdb_;
 
   RuntimeSupportBuilder* runtime_support_;
-
-  llvm::MDNode* expect_cond_[MAX_EXPECT];
 };
 
 
diff --git a/src/compiler_llvm/md_builder.cc b/src/compiler_llvm/md_builder.cc
new file mode 100644
index 0000000..f5232aa
--- /dev/null
+++ b/src/compiler_llvm/md_builder.cc
@@ -0,0 +1,99 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+#include "md_builder.h"
+
+#include "llvm/Support/MDBuilder.h"
+
+#include <string>
+
+namespace art {
+namespace compiler_llvm {
+
+
+llvm::MDNode* MDBuilder::GetTBAASpecialType(TBAASpecialType sty_id) {
+  DCHECK_GE(sty_id, 0) << "Unknown TBAA special type: " << sty_id;
+  DCHECK_LT(sty_id, MAX_TBAA_SPECIAL_TYPE) << "Unknown TBAA special type: " << sty_id;
+  DCHECK(tbaa_root_ != NULL);
+
+  llvm::MDNode*& spec_ty = tbaa_special_type_[sty_id];
+  if (spec_ty == NULL) {
+    switch (sty_id) {
+    case kTBAARegister:     spec_ty = createTBAANode("Register", tbaa_root_); break;
+    case kTBAAStackTemp:    spec_ty = createTBAANode("StackTemp", tbaa_root_); break;
+    case kTBAAHeapArray:    spec_ty = createTBAANode("HeapArray", tbaa_root_); break;
+    case kTBAAHeapInstance: spec_ty = createTBAANode("HeapInstance", tbaa_root_); break;
+    case kTBAAHeapStatic:   spec_ty = createTBAANode("HeapStatic", tbaa_root_); break;
+    case kTBAAJRuntime:     spec_ty = createTBAANode("JRuntime", tbaa_root_); break;
+    case kTBAARuntimeInfo:  spec_ty = createTBAANode("RuntimeInfo", tbaa_root_); break;
+    case kTBAAShadowFrame:  spec_ty = createTBAANode("ShadowFrame", tbaa_root_); break;
+    case kTBAAConstJObject: spec_ty = createTBAANode("ConstJObject", tbaa_root_, true); break;
+    default:
+      LOG(FATAL) << "Unknown TBAA special type: " << sty_id;
+      break;
+    }
+  }
+  return spec_ty;
+}
+
+llvm::MDNode* MDBuilder::GetTBAAMemoryJType(TBAASpecialType sty_id, JType jty_id) {
+  DCHECK(sty_id == kTBAAHeapArray ||
+         sty_id == kTBAAHeapInstance ||
+         sty_id == kTBAAHeapStatic) << "SpecialType must be array, instance, or static";
+
+  DCHECK_GE(jty_id, 0) << "Unknown JType: " << jty_id;
+  DCHECK_LT(jty_id, MAX_JTYPE) << "Unknown JType: " << jty_id;
+  DCHECK_NE(jty_id, kVoid) << "Can't load/store Void type!";
+
+  std::string name;
+  size_t sty_mapped_index = 0;
+  switch (sty_id) {
+  case kTBAAHeapArray:    sty_mapped_index = 0; name = "HeapArray "; break;
+  case kTBAAHeapInstance: sty_mapped_index = 1; name = "HeapInstance "; break;
+  case kTBAAHeapStatic:   sty_mapped_index = 2; name = "HeapStatic "; break;
+  default:
+    LOG(FATAL) << "Unknown TBAA special type: " << sty_id;
+    break;
+  }
+
+  llvm::MDNode*& spec_ty = tbaa_memory_jtype_[sty_mapped_index][jty_id];
+  if (spec_ty != NULL) {
+    return spec_ty;
+  }
+
+  switch (jty_id) {
+  case kBoolean: name += "Boolean"; break;
+  case kByte:    name += "Byte"; break;
+  case kChar:    name += "Char"; break;
+  case kShort:   name += "Short"; break;
+  case kInt:     name += "Int"; break;
+  case kLong:    name += "Long"; break;
+  case kFloat:   name += "Float"; break;
+  case kDouble:  name += "Double"; break;
+  case kObject:  name += "Object"; break;
+  default:
+    LOG(FATAL) << "Unknown JType: " << jty_id;
+    break;
+  }
+
+  spec_ty = createTBAANode(name, GetTBAASpecialType(sty_id));
+  return spec_ty;
+}
+
+
+} // namespace compiler_llvm
+} // namespace art
diff --git a/src/compiler_llvm/md_builder.h b/src/compiler_llvm/md_builder.h
new file mode 100644
index 0000000..5b02500
--- /dev/null
+++ b/src/compiler_llvm/md_builder.h
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef ART_SRC_COMPILER_LLVM_MD_BUILDER_H_
+#define ART_SRC_COMPILER_LLVM_MD_BUILDER_H_
+
+#include "backend_types.h"
+
+#include "llvm/Support/MDBuilder.h"
+
+#include <cstring>
+
+namespace llvm {
+  class LLVMContext;
+  class MDNode;
+}
+
+namespace art {
+namespace compiler_llvm {
+
+typedef llvm::MDBuilder LLVMMDBuilder;
+
+class MDBuilder : public LLVMMDBuilder {
+ public:
+  MDBuilder(llvm::LLVMContext& context) : LLVMMDBuilder(context) {
+    tbaa_root_ = createTBAARoot("Art TBAA Root");
+    std::memset(tbaa_special_type_, 0, sizeof(tbaa_special_type_));
+    std::memset(tbaa_memory_jtype_, 0, sizeof(tbaa_memory_jtype_));
+
+    // Pre-generate the MDNode for static branch prediction
+    // 64 and 4 are the llvm.expect's default values
+    expect_cond_[kLikely] = createBranchWeights(64, 4);
+    expect_cond_[kUnlikely] = createBranchWeights(4, 64);
+  }
+
+  llvm::MDNode* GetTBAASpecialType(TBAASpecialType special_ty);
+  llvm::MDNode* GetTBAAMemoryJType(TBAASpecialType special_ty, JType j_ty);
+
+  llvm::MDNode* GetBranchWeights(ExpectCond expect) {
+    DCHECK_LT(expect, MAX_EXPECT) << "MAX_EXPECT is not for branch weight";
+    return expect_cond_[expect];
+  }
+
+ private:
+  llvm::MDNode* tbaa_root_;
+  llvm::MDNode* tbaa_special_type_[MAX_TBAA_SPECIAL_TYPE];
+  // There are 3 categories of memory types will not alias: array element, instance field, and
+  // static field.
+  llvm::MDNode* tbaa_memory_jtype_[3][MAX_JTYPE];
+
+  llvm::MDNode* expect_cond_[MAX_EXPECT];
+};
+
+
+} // namespace compiler_llvm
+} // namespace art
+
+#endif // ART_SRC_COMPILER_LLVM_MD_BUILDER_H_
diff --git a/src/compiler_llvm/tbaa_info.cc b/src/compiler_llvm/tbaa_info.cc
deleted file mode 100644
index 03ef525..0000000
--- a/src/compiler_llvm/tbaa_info.cc
+++ /dev/null
@@ -1,122 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-
-#include "tbaa_info.h"
-
-#include <llvm/ADT/SmallVector.h>
-#include <llvm/ADT/StringRef.h>
-#include <llvm/Constants.h>
-#include <llvm/Metadata.h>
-#include <llvm/Type.h>
-
-
-namespace art {
-namespace compiler_llvm {
-
-
-llvm::MDNode* TBAAInfo::GetRootType() {
-  if (root_ == NULL) {
-    root_ = GenTBAANode("Art TBAA Root");
-  }
-  return root_;
-}
-
-llvm::MDNode* TBAAInfo::GetSpecialType(TBAASpecialType sty_id) {
-  DCHECK_GE(sty_id, 0) << "Unknown TBAA special type: " << sty_id;
-  DCHECK_LT(sty_id, MAX_TBAA_SPECIAL_TYPE) << "Unknown TBAA special type: " << sty_id;
-
-  llvm::MDNode*& spec_ty = special_type_[sty_id];
-  if (spec_ty == NULL) {
-    switch (sty_id) {
-    case kTBAARegister:     spec_ty = GenTBAANode("Register", GetRootType()); break;
-    case kTBAAStackTemp:    spec_ty = GenTBAANode("StackTemp", GetRootType()); break;
-    case kTBAAHeapArray:    spec_ty = GenTBAANode("HeapArray", GetRootType()); break;
-    case kTBAAHeapInstance: spec_ty = GenTBAANode("HeapInstance", GetRootType()); break;
-    case kTBAAHeapStatic:   spec_ty = GenTBAANode("HeapStatic", GetRootType()); break;
-    case kTBAAJRuntime:     spec_ty = GenTBAANode("JRuntime", GetRootType()); break;
-    case kTBAARuntimeInfo:  spec_ty = GenTBAANode("RuntimeInfo", GetRootType()); break;
-    case kTBAAShadowFrame:  spec_ty = GenTBAANode("ShadowFrame", GetRootType()); break;
-    case kTBAAConstJObject: spec_ty = GenTBAANode("ConstJObject", GetRootType(), true); break;
-    default:
-      LOG(FATAL) << "Unknown TBAA special type: " << sty_id;
-      break;
-    }
-  }
-  return spec_ty;
-}
-
-llvm::MDNode* TBAAInfo::GetMemoryJType(TBAASpecialType sty_id, JType jty_id) {
-  DCHECK(sty_id == kTBAAHeapArray ||
-         sty_id == kTBAAHeapInstance ||
-         sty_id == kTBAAHeapStatic) << "SpecialType must be array, instance, or static";
-
-  DCHECK_GE(jty_id, 0) << "Unknown JType: " << jty_id;
-  DCHECK_LT(jty_id, MAX_JTYPE) << "Unknown JType: " << jty_id;
-  DCHECK_NE(jty_id, kVoid) << "Can't load/store Void type!";
-
-  std::string name;
-  size_t sty_mapped_index = 0;
-  switch (sty_id) {
-  case kTBAAHeapArray:    sty_mapped_index = 0; name = "HeapArray "; break;
-  case kTBAAHeapInstance: sty_mapped_index = 1; name = "HeapInstance "; break;
-  case kTBAAHeapStatic:   sty_mapped_index = 2; name = "HeapStatic "; break;
-  default:
-    LOG(FATAL) << "Unknown TBAA special type: " << sty_id;
-    break;
-  }
-
-  llvm::MDNode*& spec_ty = memory_jtype_[sty_mapped_index][jty_id];
-  if (spec_ty != NULL) {
-    return spec_ty;
-  }
-
-  switch (jty_id) {
-  case kBoolean: name += "Boolean"; break;
-  case kByte:    name += "Byte"; break;
-  case kChar:    name += "Char"; break;
-  case kShort:   name += "Short"; break;
-  case kInt:     name += "Int"; break;
-  case kLong:    name += "Long"; break;
-  case kFloat:   name += "Float"; break;
-  case kDouble:  name += "Double"; break;
-  case kObject:  name += "Object"; break;
-  default:
-    LOG(FATAL) << "Unknown JType: " << jty_id;
-    break;
-  }
-
-  spec_ty = GenTBAANode(name, GetSpecialType(sty_id));
-  return spec_ty;
-}
-
-llvm::MDNode* TBAAInfo::GenTBAANode(llvm::StringRef name, llvm::MDNode* parent, bool read_only) {
-  llvm::SmallVector<llvm::Value*, 3> array_ref;
-
-  array_ref.push_back(llvm::MDString::get(context_, name));
-  if (parent != NULL) {
-    array_ref.push_back(parent);
-  }
-  if (read_only != false) {
-    array_ref.push_back(llvm::ConstantInt::get(llvm::Type::getInt1Ty(context_), read_only));
-  }
-
-  return llvm::MDNode::get(context_, array_ref);
-}
-
-
-} // namespace compiler_llvm
-} // namespace art
diff --git a/src/compiler_llvm/tbaa_info.h b/src/compiler_llvm/tbaa_info.h
deleted file mode 100644
index 9c0e250..0000000
--- a/src/compiler_llvm/tbaa_info.h
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_SRC_COMPILER_LLVM_TBAA_INFO_H_
-#define ART_SRC_COMPILER_LLVM_TBAA_INFO_H_
-
-#include "backend_types.h"
-
-#include <cstring>
-
-namespace llvm {
-  class LLVMContext;
-  class MDNode;
-  class StringRef;
-}
-
-namespace art {
-namespace compiler_llvm {
-
-
-class TBAAInfo {
- public:
-  TBAAInfo(llvm::LLVMContext& context) : context_(context), root_(NULL) {
-    std::memset(special_type_, 0, sizeof(special_type_));
-    std::memset(memory_jtype_, 0, sizeof(memory_jtype_));
-  }
-
-  llvm::MDNode* GetRootType();
-
-  llvm::MDNode* GetSpecialType(TBAASpecialType special_ty);
-
-  llvm::MDNode* GetMemoryJType(TBAASpecialType special_ty, JType j_ty);
-
-  llvm::MDNode* GenTBAANode(llvm::StringRef name,
-                            llvm::MDNode* parent = NULL,
-                            bool readonly = false);
-
- private:
-  llvm::LLVMContext& context_;
-  llvm::MDNode* root_;
-  llvm::MDNode* special_type_[MAX_TBAA_SPECIAL_TYPE];
-  // There are 3 categories of memory types will not alias: array element, instance field, and
-  // static field.
-  llvm::MDNode* memory_jtype_[3][MAX_JTYPE];
-};
-
-
-} // namespace compiler_llvm
-} // namespace art
-
-#endif // ART_SRC_COMPILER_LLVM_TBAA_INFO_H_