Create constant expression casts instead of constant instructions if possible
[oota-llvm.git] / lib / ExecutionEngine / ExecutionEngine.cpp
index 3d190aa0f81d5d66dbc892baff8023b2037c14a2..a6f71266d78ad49a812b084d0d3897f69dc38ab5 100644 (file)
@@ -12,6 +12,7 @@
 #include "llvm/Module.h"
 #include "llvm/Target/TargetData.h"
 #include "Support/Statistic.h"
+#include <dlfcn.h>
 
 Statistic<> NumInitBytes("lli", "Number of bytes of global vars initialized");
 
@@ -29,10 +30,28 @@ void *ExecutionEngine::getPointerToGlobal(const GlobalValue *GV) {
 
 GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
   GenericValue Result;
-#define GET_CONST_VAL(TY, CLASS) \
-  case Type::TY##TyID: Result.TY##Val = cast<CLASS>(C)->getValue(); break
+
+  if (ConstantExpr *CE = (ConstantExpr*)dyn_cast<ConstantExpr>(C))
+    switch (CE->getOpcode()) {
+    case Instruction::GetElementPtr: {
+      Result = getConstantValue(cast<Constant>(CE->getOperand(0)));
+      std::vector<Value*> Indexes(CE->op_begin()+1, CE->op_end());
+      uint64_t Offset =
+        TD->getIndexedOffset(CE->getOperand(0)->getType(), Indexes);
+                             
+      Result.LongVal += Offset;
+      return Result;
+    }
+
+    default:
+      std::cerr << "ConstantExpr not handled as global var init: " << *CE
+                << "\n";
+      abort();
+    }
 
   switch (C->getType()->getPrimitiveID()) {
+#define GET_CONST_VAL(TY, CLASS) \
+  case Type::TY##TyID: Result.TY##Val = cast<CLASS>(C)->getValue(); break
     GET_CONST_VAL(Bool   , ConstantBool);
     GET_CONST_VAL(UByte  , ConstantUInt);
     GET_CONST_VAL(SByte  , ConstantSInt);
@@ -57,6 +76,7 @@ GenericValue ExecutionEngine::getConstantValue(const Constant *C) {
     break;
   default:
     std::cout << "ERROR: Constant unimp for type: " << C->getType() << "\n";
+    abort();
   }
   return Result;
 }
@@ -72,6 +92,7 @@ void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr,
     case Type::ShortTyID:   Ptr->Untyped[0] = Val.UShortVal & 255;
                             Ptr->Untyped[1] = (Val.UShortVal >> 8) & 255;
                             break;
+    Store4BytesLittleEndian:
     case Type::FloatTyID:
     case Type::UIntTyID:
     case Type::IntTyID:     Ptr->Untyped[0] =  Val.UIntVal        & 255;
@@ -79,10 +100,11 @@ void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr,
                             Ptr->Untyped[2] = (Val.UIntVal >> 16) & 255;
                             Ptr->Untyped[3] = (Val.UIntVal >> 24) & 255;
                             break;
+    case Type::PointerTyID: if (CurMod.has32BitPointers())
+                              goto Store4BytesLittleEndian;
     case Type::DoubleTyID:
     case Type::ULongTyID:
-    case Type::LongTyID:    
-    case Type::PointerTyID: Ptr->Untyped[0] =  Val.ULongVal        & 255;
+    case Type::LongTyID:    Ptr->Untyped[0] =  Val.ULongVal        & 255;
                             Ptr->Untyped[1] = (Val.ULongVal >>  8) & 255;
                             Ptr->Untyped[2] = (Val.ULongVal >> 16) & 255;
                             Ptr->Untyped[3] = (Val.ULongVal >> 24) & 255;
@@ -103,6 +125,7 @@ void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr,
     case Type::ShortTyID:   Ptr->Untyped[1] = Val.UShortVal & 255;
                             Ptr->Untyped[0] = (Val.UShortVal >> 8) & 255;
                             break;
+    Store4BytesBigEndian:
     case Type::FloatTyID:
     case Type::UIntTyID:
     case Type::IntTyID:     Ptr->Untyped[3] =  Val.UIntVal        & 255;
@@ -110,10 +133,11 @@ void ExecutionEngine::StoreValueToMemory(GenericValue Val, GenericValue *Ptr,
                             Ptr->Untyped[1] = (Val.UIntVal >> 16) & 255;
                             Ptr->Untyped[0] = (Val.UIntVal >> 24) & 255;
                             break;
+    case Type::PointerTyID: if (CurMod.has32BitPointers())
+                              goto Store4BytesBigEndian;
     case Type::DoubleTyID:
     case Type::ULongTyID:
-    case Type::LongTyID:    
-    case Type::PointerTyID: Ptr->Untyped[7] =  Val.ULongVal        & 255;
+    case Type::LongTyID:    Ptr->Untyped[7] =  Val.ULongVal        & 255;
                             Ptr->Untyped[6] = (Val.ULongVal >>  8) & 255;
                             Ptr->Untyped[5] = (Val.ULongVal >> 16) & 255;
                             Ptr->Untyped[4] = (Val.ULongVal >> 24) & 255;
@@ -213,15 +237,16 @@ void ExecutionEngine::emitGlobals() {
 
       DEBUG(std::cerr << "Global '" << I->getName() << "' -> "
                      << (void*)GlobalAddress[I] << "\n");
-    } else if (I->getName() == "stdout") {
-      GlobalAddress[I] = &stdout;
-    } else if (I->getName() == "stderr") {
-      GlobalAddress[I] = &stderr;
-    } else if (I->getName() == "stdin") {
-      GlobalAddress[I] = &stdin;
     } else {
-      std::cerr << "Global: " << I->getName() << "\n";
-      assert(0 && "References to external globals not handled yet!");
+      // External variable reference, try to use dlsym to get a pointer to it in
+      // the LLI image.
+      if (void *SymAddr = dlsym(0, I->getName().c_str()))
+        GlobalAddress[I] = SymAddr;
+      else {
+        std::cerr << "Could not resolve external global address: "
+                  << I->getName() << "\n";
+        abort();
+      }
     }
   
   // Now that all of the globals are set up in memory, loop through them all and