add bc reader/writer support for inline asm
authorChris Lattner <sabre@nondot.org>
Wed, 25 Jan 2006 23:08:15 +0000 (23:08 +0000)
committerChris Lattner <sabre@nondot.org>
Wed, 25 Jan 2006 23:08:15 +0000 (23:08 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@25621 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Bytecode/Reader/Reader.cpp
lib/Bytecode/Reader/Reader.h
lib/Bytecode/Writer/SlotCalculator.cpp
lib/Bytecode/Writer/SlotCalculator.h
lib/Bytecode/Writer/Writer.cpp
lib/Bytecode/Writer/WriterInternals.h

index d2660e3faba0759af0c168b58385a967802dd954..d142aacfa506d5581c5687868488cb923a38b0df 100644 (file)
@@ -22,6 +22,7 @@
 #include "llvm/BasicBlock.h"
 #include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
+#include "llvm/InlineAsm.h"
 #include "llvm/Instructions.h"
 #include "llvm/SymbolTable.h"
 #include "llvm/Bytecode/Format.h"
@@ -1404,7 +1405,7 @@ void BytecodeReader::ParseTypes(TypeListTy &Tab, unsigned NumEntries){
 }
 
 /// Parse a single constant value
-Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
+Value *BytecodeReader::ParseConstantPoolValue(unsigned TypeID) {
   // We must check for a ConstantExpr before switching by type because
   // a ConstantExpr can be of any type, and has no explicit value.
   //
@@ -1412,11 +1413,32 @@ Constant *BytecodeReader::ParseConstantValue(unsigned TypeID) {
   unsigned isExprNumArgs = read_vbr_uint();
 
   if (isExprNumArgs) {
-    // 'undef' is encoded with 'exprnumargs' == 1.
-    if (!hasNoUndefValue)
-      if (--isExprNumArgs == 0)
+    if (!hasNoUndefValue) {
+      // 'undef' is encoded with 'exprnumargs' == 1.
+      if (isExprNumArgs == 1)
         return UndefValue::get(getType(TypeID));
 
+      // Inline asm is encoded with exprnumargs == ~0U.
+      if (isExprNumArgs == ~0U) {
+        std::string AsmStr = read_str();
+        std::string ConstraintStr = read_str();
+        unsigned Flags = read_vbr_uint();
+        
+        const PointerType *PTy = dyn_cast<PointerType>(getType(TypeID));
+        const FunctionType *FTy = 
+          PTy ? dyn_cast<FunctionType>(PTy->getElementType()) : 0;
+
+        if (!FTy || !InlineAsm::Verify(FTy, ConstraintStr))
+          error("Invalid constraints for inline asm");
+        if (Flags & ~1U)
+          error("Invalid flags for inline asm");
+        bool HasSideEffects = Flags & 1;
+        return InlineAsm::get(FTy, AsmStr, ConstraintStr, HasSideEffects);
+      }
+      
+      --isExprNumArgs;
+    }
+
     // FIXME: Encoding of constant exprs could be much more compact!
     std::vector<Constant*> ArgVec;
     ArgVec.reserve(isExprNumArgs);
@@ -1695,9 +1717,9 @@ void BytecodeReader::ParseConstantPool(ValueTable &Tab,
       ParseStringConstants(NumEntries, Tab);
     } else {
       for (unsigned i = 0; i < NumEntries; ++i) {
-        Constant *C = ParseConstantValue(Typ);
-        assert(C && "ParseConstantValue returned NULL!");
-        unsigned Slot = insertValue(C, Typ, Tab);
+        Value *V = ParseConstantPoolValue(Typ);
+        assert(V && "ParseConstantPoolValue returned NULL!");
+        unsigned Slot = insertValue(V, Typ, Tab);
 
         // If we are reading a function constant table, make sure that we adjust
         // the slot number to be the real global constant number.
@@ -1705,7 +1727,8 @@ void BytecodeReader::ParseConstantPool(ValueTable &Tab,
         if (&Tab != &ModuleValues && Typ < ModuleValues.size() &&
             ModuleValues[Typ])
           Slot += ModuleValues[Typ]->size();
-        ResolveReferencesToConstant(C, Typ, Slot);
+        if (Constant *C = dyn_cast<Constant>(V))
+          ResolveReferencesToConstant(C, Typ, Slot);
       }
     }
   }
index 25410838d34441937bf84aef038bad26226c60ac..21eb8462fb2f03106f1a6558567014d84d11ead3 100644 (file)
@@ -229,8 +229,8 @@ protected:
   void ParseConstantPool(ValueTable& Values, TypeListTy& Types,
                          bool isFunction);
 
-  /// @brief Parse a single constant value
-  Constant* ParseConstantValue(unsigned TypeID);
+  /// @brief Parse a single constant pool value
+  Value *ParseConstantPoolValue(unsigned TypeID);
 
   /// @brief Parse a block of types constants
   void ParseTypes(TypeListTy &Tab, unsigned NumEntries);
index c6aba09fe51d7721dccc5d74f978f76ab73bcd4c..26bd1be8f67feee3b62c49a523b485ce74e9842b 100644 (file)
@@ -18,6 +18,7 @@
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
 #include "llvm/Function.h"
+#include "llvm/InlineAsm.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
 #include "llvm/SymbolTable.h"
@@ -27,7 +28,6 @@
 #include "llvm/ADT/STLExtras.h"
 #include <algorithm>
 #include <functional>
-
 using namespace llvm;
 
 #if 0
@@ -181,11 +181,13 @@ void SlotCalculator::processModule() {
   SC_DEBUG("Inserting function constants:\n");
   for (Module::const_iterator F = TheModule->begin(), E = TheModule->end();
        F != E; ++F) {
-    for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I){
-      for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op)
-        if (isa<Constant>(I->getOperand(op)) &&
-            !isa<GlobalValue>(I->getOperand(op)))
-          getOrCreateSlot(I->getOperand(op));
+    for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I) {
+      for (User::const_op_iterator OI = I->op_begin(), E = I->op_end(); 
+           OI != E; ++OI) {
+        if ((isa<Constant>(*OI) && !isa<GlobalValue>(*OI)) ||
+            isa<InlineAsm>(*OI))
+          getOrCreateSlot(*OI);
+      }
       getOrCreateSlot(I->getType());
     }
     processSymbolTableConstants(&F->getSymbolTable());
@@ -286,7 +288,7 @@ void SlotCalculator::incorporateFunction(const Function *F) {
   for(Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end(); I != E; ++I)
     getOrCreateSlot(I);
 
-  if ( !ModuleContainsAllFunctionConstants ) {
+  if (!ModuleContainsAllFunctionConstants) {
     // Iterate over all of the instructions in the function, looking for
     // constant values that are referenced.  Add these to the value pools
     // before any nonconstant values.  This will be turned into the constant
@@ -295,12 +297,9 @@ void SlotCalculator::incorporateFunction(const Function *F) {
 
     // Emit all of the constants that are being used by the instructions in
     // the function...
-    constant_iterator CI = constant_begin(F);
-    constant_iterator CE = constant_end(F);
-    while ( CI != CE ) {
-      this->getOrCreateSlot(*CI);
-      ++CI;
-    }
+    for (constant_iterator CI = constant_begin(F), CE = constant_end(F);
+         CI != CE; ++CI)
+      getOrCreateSlot(*CI);
 
     // If there is a symbol table, it is possible that the user has names for
     // constants that are not being used.  In this case, we will have problems
index 63927ca8142e010d3ad4a6d6eecac2cd54630967..e88a88f726b3b33435f520702efdf776ac51a916 100644 (file)
@@ -74,9 +74,9 @@ class SlotCalculator {
   SlotCalculator(const SlotCalculator &);  // DO NOT IMPLEMENT
   void operator=(const SlotCalculator &);  // DO NOT IMPLEMENT
 public:
-  SlotCalculator(const Module *M );
+  SlotCalculator(const Module *M);
   // Start out in incorp state
-  SlotCalculator(const Function *F );
+  SlotCalculator(const Function *F);
 
   /// getSlot - Return the slot number of the specified value in it's type
   /// plane.  This returns < 0 on error!
@@ -146,19 +146,19 @@ private:
   // they haven't been inserted already, they get inserted, otherwise
   // they are ignored.
   //
-  int getOrCreateSlot(const Value *D);
-  int getOrCreateSlot(const TypeT);
+  int getOrCreateSlot(const Value *V);
+  int getOrCreateSlot(const Type *T);
 
   // insertValue - Insert a value into the value table... Return the
   // slot that it occupies, or -1 if the declaration is to be ignored
   // because of the IgnoreNamedNodes flag.
   //
   int insertValue(const Value *D, bool dontIgnore = false);
-  int insertType(const Type* T, bool dontIgnore = false );
+  int insertType(const Type *T, bool dontIgnore = false);
 
   // doInsertValue - Small helper function to be called only be insertVal.
-  int doInsertValue(const Value *D);
-  int doInsertType(const Type*T);
+  int doInsertValue(const Value *V);
+  int doInsertType(const Type *T);
 
   // processModule - Process all of the module level function declarations and
   // types that are available.
index bfbce91c56eb9640da7e7982902a86efa4f1e5d8..80abcacee97d6f09e4ea9ccddb2c24be123727ff 100644 (file)
@@ -22,6 +22,7 @@
 #include "llvm/CallingConv.h"
 #include "llvm/Constants.h"
 #include "llvm/DerivedTypes.h"
+#include "llvm/InlineAsm.h"
 #include "llvm/Instructions.h"
 #include "llvm/Module.h"
 #include "llvm/SymbolTable.h"
@@ -389,6 +390,19 @@ void BytecodeWriter::outputConstant(const Constant *CPV) {
   return;
 }
 
+/// outputInlineAsm - InlineAsm's get emitted to the constant pool, so they can
+/// be shared by multiple uses.
+void BytecodeWriter::outputInlineAsm(const InlineAsm *IA) {
+  // Output a marker, so we know when we have one one parsing the constant pool.
+  // Note that this encoding is 5 bytes: not very efficient for a marker.  Since
+  // unique inline asms are rare, this should hardly matter.
+  output_vbr(~0U);
+  
+  output(IA->getAsmString());
+  output(IA->getConstraintString());
+  output_vbr(unsigned(IA->hasSideEffects()));
+}
+
 void BytecodeWriter::outputConstantStrings() {
   SlotCalculator::string_iterator I = Table.string_begin();
   SlotCalculator::string_iterator E = Table.string_end();
@@ -847,7 +861,8 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*>
     /*empty*/;
 
   unsigned NC = ValNo;              // Number of constants
-  for (; NC < Plane.size() && (isa<Constant>(Plane[NC])); NC++)
+  for (; NC < Plane.size() && (isa<Constant>(Plane[NC]) || 
+                               isa<InlineAsm>(Plane[NC])); NC++)
     /*empty*/;
   NC -= ValNo;                      // Convert from index into count
   if (NC == 0) return;              // Skip empty type planes...
@@ -866,9 +881,10 @@ void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*>
 
   for (unsigned i = ValNo; i < ValNo+NC; ++i) {
     const Value *V = Plane[i];
-    if (const Constant *C = dyn_cast<Constant>(V)) {
+    if (const Constant *C = dyn_cast<Constant>(V))
       outputConstant(C);
-    }
+    else
+      outputInlineAsm(cast<InlineAsm>(V));
   }
 }
 
index 15dd92db1ec393320e69d473452542315250eb13..f8c276e8581a9563f5e27c6e78c21d40021b46ed 100644 (file)
@@ -24,6 +24,7 @@
 #include <vector>
 
 namespace llvm {
+  class InlineAsm;
 
 class BytecodeWriter {
   std::vector<unsigned char> &Out;
@@ -68,6 +69,7 @@ private:
   void outputConstantsInPlane(const std::vector<const Value*> &Plane,
                               unsigned StartNo);
   void outputConstant(const Constant *CPV);
+  void outputInlineAsm(const InlineAsm *IA);
   void outputType(const Type *T);
 
   /// @brief Unsigned integer output primitive
@@ -88,7 +90,7 @@ private:
   /// @brief Signed 32-bit variable bit rate output primitive.
   inline void output_vbr(int i);
 
-  inline void output(const std::string &s );
+  inline void output(const std::string &s);
 
   inline void output_data(const void *Ptr, const void *End);