Add Compiler::ArchType. And fix the CodeModel and NoFramePointerElim.

Details: Add static member Compiler::ArchType and determine its value during the
Compiler::GlobalInitialization() according to the given triple.

Determine values of the option NoFramePointerElim and CodeModel in
CompilerOption.

Change-Id: I4432ee0c81d379a61df9355bc8079f2093936563
diff --git a/lib/ExecutionEngine/Compiler.cpp b/lib/ExecutionEngine/Compiler.cpp
index 4545c0e..ff7f0f1 100644
--- a/lib/ExecutionEngine/Compiler.cpp
+++ b/lib/ExecutionEngine/Compiler.cpp
@@ -40,7 +40,6 @@
 #include "Transforms/BCCTransforms.h"
 
 #include "llvm/ADT/StringRef.h"
-#include "llvm/ADT/Triple.h"
 
 #include "llvm/Analysis/Passes.h"
 
@@ -109,6 +108,7 @@
 llvm::CodeGenOpt::Level Compiler::CodeGenOptLevel;
 
 std::string Compiler::Triple;
+llvm::Triple::ArchType Compiler::ArchType;
 
 std::string Compiler::CPU;
 
@@ -145,30 +145,31 @@
   // Set Triple, CPU and Features here
   Triple = TARGET_TRIPLE_STRING;
 
-  // Determine target_archtype
+  // Determine ArchType
 #if defined(__HOST__)
-  std::string Err;
-  llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
-  llvm::Triple::ArchType target_archtype;
-  if (Target == 0) {
-    target_archtype = llvm::Triple::UnknownArch;
-  } else {
-    const char *target_llvm_name = Target->getName();
-    target_archtype = llvm::Triple::getArchTypeForLLVMName(target_llvm_name);
+  {
+    std::string Err;
+    llvm::Target const *Target = llvm::TargetRegistry::lookupTarget(Triple, Err);
+    if (Target == NULL) {
+      ArchType = llvm::Triple::getArchTypeForLLVMName(Target->getName());
+    } else {
+      ArchType = llvm::Triple::UnknownArch;
+      ALOGE("%s", Err.c_str());
+    }
   }
 #elif defined(DEFAULT_ARM_CODEGEN)
-  const llvm::Triple::ArchType target_archtype = llvm::Triple::arm;
+  ArchType = llvm::Triple::arm;
 #elif defined(DEFAULT_MIPS_CODEGEN)
-  const llvm::Triple::ArchType target_archtype = llvm::Triple::mipsel;
+  ArchType = llvm::Triple::mipsel;
 #elif defined(DEFAULT_X86_CODEGEN)
-  const llvm::Triple::ArchType target_archtype = llvm::Triple::x86;
+  ArchType = llvm::Triple::x86;
 #elif defined(DEFAULT_X86_64_CODEGEN)
-  const llvm::Triple::ArchType target_archtype = llvm::Triple::x86_64;
+  ArchType = llvm::Triple::x86_64;
 #else
-  const llvm::Triple::ArchType target_archtype = llvm::Triple::UnknownArch;
+  ArchType = llvm::Triple::UnknownArch;
 #endif
 
-  if (target_archtype == llvm::Triple::arm || target_archtype == llvm::Triple::thumb) {
+  if ((ArchType == llvm::Triple::arm) || (ArchType == llvm::Triple::thumb)) {
 #  if defined(ARCH_ARM_HAVE_VFP)
     Features.push_back("+vfp3");
 #  if !defined(ARCH_ARM_HAVE_VFP_D32)
@@ -326,41 +327,6 @@
     FeaturesStr = F.getString();
   }
 
-  // Determine if code_model_is_medium
-  // And determine if no_frame_pointer_elimination
-#if defined(__HOST__)
-  bool code_model_is_medium;
-  bool no_frame_pointer_elimination;
-
-  {
-    // open a new scope otherwise compiler complains constructor of the
-    // folloinwg two being bypassed by previous 'goto' statement
-    const char *target_llvm_name = Target->getName();
-    const llvm::Triple::ArchType target_archtype = llvm::Triple::getArchTypeForLLVMName(target_llvm_name);
-    // Data address in X86_64 architecture may reside in a far-away place
-    code_model_is_medium = target_archtype == llvm::Triple::x86_64;
-    // Disable frame pointer elimination optimization for X86_64 and X86
-    no_frame_pointer_elimination = (target_archtype == llvm::Triple::x86_64 ||
-                                    target_archtype == llvm::Triple::x86);
-  }
-#elif defined(DEFAULT_X86_64_CODEGEN)
-# define code_model_is_medium           true
-# define no_frame_pointer_elimination   true
-#elif defined(DEFAULT_X86_CODEGEN)
-# define code_model_is_medium           false
-# define no_frame_pointer_elimination   true
-#else
-# define code_model_is_medium           false
-# define no_frame_pointer_elimination   false
-#endif
-
-  // Setup LLVM Target Machine Options
-  option.TargetOpt.NoFramePointerElim = no_frame_pointer_elimination;
-
-  // This is set for the linker (specify how large of the virtual addresses
-  // we can access for all unknown symbols.)
-  option.CodeModelOpt = code_model_is_medium ? llvm::CodeModel::Medium : llvm::CodeModel::Small;
-
   // Create LLVM Target Machine
   TM = Target->createTargetMachine(Triple, CPU, FeaturesStr,
                                    option.TargetOpt,
diff --git a/lib/ExecutionEngine/Compiler.h b/lib/ExecutionEngine/Compiler.h
index 5082d9e..f436df0 100644
--- a/lib/ExecutionEngine/Compiler.h
+++ b/lib/ExecutionEngine/Compiler.h
@@ -29,6 +29,7 @@
 #include "llvm/ADT/OwningPtr.h"
 #include "llvm/ADT/StringRef.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/Triple.h"
 #include "llvm/Target/TargetMachine.h"
 
 #include <stddef.h>
@@ -61,6 +62,7 @@
     // If given, this will be the name of the target triple to compile for.
     // If not given, the initial values defined in this file will be used.
     static std::string Triple;
+    static llvm::Triple::ArchType ArchType;
 
     static llvm::CodeGenOpt::Level CodeGenOptLevel;
 
@@ -121,6 +123,10 @@
       return Triple;
     }
 
+    static llvm::Triple::ArchType getTargetArchType() {
+      return ArchType;
+    }
+
     void registerSymbolCallback(BCCSymbolLookupFn pFn, void *pContext) {
       mpSymbolLookupFn = pFn;
       mpSymbolLookupContext = pContext;
diff --git a/lib/ExecutionEngine/CompilerOption.h b/lib/ExecutionEngine/CompilerOption.h
index 92754f0..cb6a5de 100644
--- a/lib/ExecutionEngine/CompilerOption.h
+++ b/lib/ExecutionEngine/CompilerOption.h
@@ -18,6 +18,7 @@
 #define BCC_COMPILER_OPTION_H
 
 #include "Config.h"
+#include "Compiler.h"
 
 #include "llvm/Target/TargetOptions.h"
 #include "llvm/Support/CodeGen.h"
@@ -34,10 +35,29 @@
   // here means the configuration for running RenderScript (more specifically,
   // one can declare a CompilerOption object (call default constructor) and then
   // pass to the Compiler::compiler() without any modification for RenderScript,
-  // see Script::prepareExecutable(...))
+  // see Script::prepareExecutable(...)).
+  //
+  // Must be invoked after call Compiler::GlobalInitialization() at least once.
+  //
   CompilerOption() {
     //-- Setup options to llvm::TargetMachine --//
 
+    //-- Setup Frame Pointer Elimination Optimization --//
+#if defined(__HOST__)
+    // Disable frame pointer elimination optimization for X86_64 and X86
+    if ((Compiler::getTargetArchType() == llvm::Triple::x86_64) ||
+        (Compiler::getTargetArchType() == llvm::Triple::x86))
+      TargetOpt.NoFramePointerElim = true;
+    else
+      TargetOpt.NoFramePointerElim = false;
+#elif defined(DEFAULT_X86_64_CODEGEN)
+    TargetOpt.NoFramePointerElim = true;
+#elif defined(DEFAULT_X86_CODEGEN)
+    TargetOpt.NoFramePointerElim = true;
+#else
+    TargetOpt.NoFramePointerElim = false;
+#endif
+
     // Use hardfloat ABI
     //
     // TODO(all): Need to detect the CPU capability and decide whether to use
@@ -51,6 +71,19 @@
     //-- Setup relocation model  --//
     RelocModelOpt = llvm::Reloc::Static;
 
+    //-- Setup code model  --//
+#if defined(__HOST__)
+    // Data address in X86_64 architecture may reside in a far-away place
+    if (Compiler::getTargetArchType() == llvm::Triple::x86_64)
+      CodeModelOpt = llvm::CodeModel::Medium;
+    else
+      CodeModelOpt = llvm::CodeModel::Small;
+#elif defined(DEFAULT_X86_64_CODEGEN)
+    CodeModelOpt = llvm::CodeModel::Medium;
+#else
+    CodeModelOpt = llvm::CodeModel::Small;
+#endif
+
     //-- Load the result object after successful compilation  --//
     LoadAfterCompile = true;
   }