Add constraints to Instruction class.
[oota-llvm.git] / lib / Target / TargetData.cpp
index ad13b1ef4e38ee390919897fd43bf0d97969b0c2..03a232c67144f334b7d8617a423743d0170d3535 100644 (file)
@@ -95,34 +95,7 @@ unsigned StructLayout::getElementContainingOffset(uint64_t Offset) const {
 //                       TargetData Class Implementation
 //===----------------------------------------------------------------------===//
 
-TargetData::TargetData(const std::string &TargetName,
-                       bool isLittleEndian, unsigned char PtrSize,
-                       unsigned char PtrAl, unsigned char DoubleAl,
-                       unsigned char FloatAl, unsigned char LongAl,
-                       unsigned char IntAl, unsigned char ShortAl,
-                       unsigned char ByteAl, unsigned char BoolAl) {
-
-  // If this assert triggers, a pass "required" TargetData information, but the
-  // top level tool did not provide one for it.  We do not want to default
-  // construct, or else we might end up using a bad endianness or pointer size!
-  //
-  assert(!TargetName.empty() &&
-         "ERROR: Tool did not specify a target data to use!");
-
-  LittleEndian     = isLittleEndian;
-  PointerSize      = PtrSize;
-  PointerAlignment = PtrAl;
-  DoubleAlignment  = DoubleAl;
-  FloatAlignment   = FloatAl;
-  LongAlignment    = LongAl;
-  IntAlignment     = IntAl;
-  ShortAlignment   = ShortAl;
-  ByteAlignment    = ByteAl;
-  BoolAlignment    = BoolAl;
-}
-
-TargetData::TargetData(const std::string &TargetName,
-                       const std::string &TargetDescription) {
+void TargetData::init(const std::string &TargetDescription) {
   std::string temp = TargetDescription;
   
   LittleEndian = false;
@@ -136,7 +109,7 @@ TargetData::TargetData(const std::string &TargetName,
   ByteAlignment  = 1;
   BoolAlignment   = 1;
   
-  while (temp.length() > 0) {
+  while (!temp.empty()) {
     std::string token = getToken(temp, "-");
     
     char signal = getToken(token, ":")[0];
@@ -153,31 +126,24 @@ TargetData::TargetData(const std::string &TargetName,
       PointerAlignment = atoi(getToken(token,":").c_str()) / 8;
       break;
     case 'd':
-      token = getToken(token,":"); //Ignore the size
       DoubleAlignment = atoi(getToken(token,":").c_str()) / 8;
       break;
     case 'f':
-      token = getToken(token, ":"); //Ignore the size
       FloatAlignment = atoi(getToken(token, ":").c_str()) / 8;
       break;
     case 'l':
-      token = getToken(token, ":"); //Ignore the size
       LongAlignment = atoi(getToken(token, ":").c_str()) / 8;
       break;
     case 'i':
-      token = getToken(token, ":"); //Ignore the size
       IntAlignment = atoi(getToken(token, ":").c_str()) / 8;
       break;
     case 's':
-      token = getToken(token, ":"); //Ignore the size
       ShortAlignment = atoi(getToken(token, ":").c_str()) / 8;
       break;
     case 'b':
-      token = getToken(token, ":"); //Ignore the size
       ByteAlignment = atoi(getToken(token, ":").c_str()) / 8;
       break;
     case 'B':
-      token = getToken(token, ":"); //Ignore the size
       BoolAlignment = atoi(getToken(token, ":").c_str()) / 8;
       break;
     default:
@@ -186,7 +152,7 @@ TargetData::TargetData(const std::string &TargetName,
   }
 }
 
-TargetData::TargetData(const std::string &ToolName, const Module *M) {
+TargetData::TargetData(const Module *M) {
   LittleEndian     = M->getEndianness() != Module::BigEndian;
   PointerSize      = M->getPointerSize() != Module::Pointer64 ? 4 : 8;
   PointerAlignment = PointerSize;
@@ -364,7 +330,7 @@ uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
   for (unsigned CurIDX = 0; CurIDX != Idx.size(); ++CurIDX, ++TI) {
     if (const StructType *STy = dyn_cast<StructType>(*TI)) {
       assert(Idx[CurIDX]->getType() == Type::UIntTy && "Illegal struct idx");
-      unsigned FieldNo = cast<ConstantUInt>(Idx[CurIDX])->getValue();
+      unsigned FieldNo = cast<ConstantInt>(Idx[CurIDX])->getZExtValue();
 
       // Get structure layout information...
       const StructLayout *Layout = getStructLayout(STy);
@@ -380,7 +346,7 @@ uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
       Ty = cast<SequentialType>(Ty)->getElementType();
 
       // Get the array index and the size of each array element.
-      int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getRawValue();
+      int64_t arrayIdx = cast<ConstantInt>(Idx[CurIDX])->getSExtValue();
       Result += arrayIdx * (int64_t)getTypeSize(Ty);
     }
   }
@@ -388,3 +354,26 @@ uint64_t TargetData::getIndexedOffset(const Type *ptrTy,
   return Result;
 }
 
+/// getPreferredAlignmentLog - Return the preferred alignment of the
+/// specified global, returned in log form.  This includes an explicitly
+/// requested alignment (if the global has one).
+unsigned TargetData::getPreferredAlignmentLog(const GlobalVariable *GV) const {
+  const Type *ElemType = GV->getType()->getElementType();
+  unsigned Alignment = getTypeAlignmentShift(ElemType);
+  if (GV->getAlignment() > (1U << Alignment))
+    Alignment = Log2_32(GV->getAlignment());
+  
+  if (GV->hasInitializer()) {
+    // Always round up alignment of global doubles to 8 bytes.
+    if (GV->getType()->getElementType() == Type::DoubleTy && Alignment < 3)
+      Alignment = 3;
+    if (Alignment < 4) {
+      // If the global is not external, see if it is large.  If so, give it a
+      // larger alignment.
+      if (getTypeSize(ElemType) > 128)
+        Alignment = 4;    // 16-byte alignment.
+    }
+  }
+  return Alignment;
+}
+