mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-14 14:24:05 +00:00
* Remove trailing whitespace
* Convert tabs to spaces git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@21418 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
@ -1,10 +1,10 @@
|
|||||||
//===-- SlotCalculator.cpp - Calculate what slots values land in ----------===//
|
//===-- SlotCalculator.cpp - Calculate what slots values land in ----------===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
// This file was developed by the LLVM research group and is distributed under
|
// This file was developed by the LLVM research group and is distributed under
|
||||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This file implements a useful analysis step to figure out what numbered slots
|
// This file implements a useful analysis step to figure out what numbered slots
|
||||||
@ -150,7 +150,7 @@ void SlotCalculator::processModule() {
|
|||||||
TypePlane &Plane = Table[plane];
|
TypePlane &Plane = Table[plane];
|
||||||
unsigned FirstNonStringID = 0;
|
unsigned FirstNonStringID = 0;
|
||||||
for (unsigned i = 0, e = Plane.size(); i != e; ++i)
|
for (unsigned i = 0, e = Plane.size(); i != e; ++i)
|
||||||
if (isa<ConstantAggregateZero>(Plane[i]) ||
|
if (isa<ConstantAggregateZero>(Plane[i]) ||
|
||||||
(isa<ConstantArray>(Plane[i]) &&
|
(isa<ConstantArray>(Plane[i]) &&
|
||||||
cast<ConstantArray>(Plane[i])->isString())) {
|
cast<ConstantArray>(Plane[i])->isString())) {
|
||||||
// Check to see if we have to shuffle this string around. If not,
|
// Check to see if we have to shuffle this string around. If not,
|
||||||
@ -158,7 +158,7 @@ void SlotCalculator::processModule() {
|
|||||||
if (i != FirstNonStringID) {
|
if (i != FirstNonStringID) {
|
||||||
// Swap the plane entries....
|
// Swap the plane entries....
|
||||||
std::swap(Plane[i], Plane[FirstNonStringID]);
|
std::swap(Plane[i], Plane[FirstNonStringID]);
|
||||||
|
|
||||||
// Keep the NodeMap up to date.
|
// Keep the NodeMap up to date.
|
||||||
NodeMap[Plane[i]] = i;
|
NodeMap[Plane[i]] = i;
|
||||||
NodeMap[Plane[FirstNonStringID]] = FirstNonStringID;
|
NodeMap[Plane[FirstNonStringID]] = FirstNonStringID;
|
||||||
@ -167,14 +167,14 @@ void SlotCalculator::processModule() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Scan all of the functions for their constants, which allows us to emit
|
// Scan all of the functions for their constants, which allows us to emit
|
||||||
// more compact modules. This is optional, and is just used to compactify
|
// more compact modules. This is optional, and is just used to compactify
|
||||||
// the constants used by different functions together.
|
// the constants used by different functions together.
|
||||||
//
|
//
|
||||||
// This functionality tends to produce smaller bytecode files. This should
|
// This functionality tends to produce smaller bytecode files. This should
|
||||||
// not be used in the future by clients that want to, for example, build and
|
// not be used in the future by clients that want to, for example, build and
|
||||||
// emit functions on the fly. For now, however, it is unconditionally
|
// emit functions on the fly. For now, however, it is unconditionally
|
||||||
// enabled.
|
// enabled.
|
||||||
ModuleContainsAllFunctionConstants = true;
|
ModuleContainsAllFunctionConstants = true;
|
||||||
|
|
||||||
@ -183,7 +183,7 @@ void SlotCalculator::processModule() {
|
|||||||
F != E; ++F) {
|
F != E; ++F) {
|
||||||
for (const_inst_iterator I = inst_begin(F), E = inst_end(F); I != E; ++I){
|
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)
|
for (unsigned op = 0, e = I->getNumOperands(); op != e; ++op)
|
||||||
if (isa<Constant>(I->getOperand(op)) &&
|
if (isa<Constant>(I->getOperand(op)) &&
|
||||||
!isa<GlobalValue>(I->getOperand(op)))
|
!isa<GlobalValue>(I->getOperand(op)))
|
||||||
getOrCreateSlot(I->getOperand(op));
|
getOrCreateSlot(I->getOperand(op));
|
||||||
getOrCreateSlot(I->getType());
|
getOrCreateSlot(I->getType());
|
||||||
@ -244,7 +244,7 @@ void SlotCalculator::processSymbolTable(const SymbolTable *ST) {
|
|||||||
getOrCreateSlot(TI->second);
|
getOrCreateSlot(TI->second);
|
||||||
|
|
||||||
// Now do the values.
|
// Now do the values.
|
||||||
for (SymbolTable::plane_const_iterator PI = ST->plane_begin(),
|
for (SymbolTable::plane_const_iterator PI = ST->plane_begin(),
|
||||||
PE = ST->plane_end(); PI != PE; ++PI)
|
PE = ST->plane_end(); PI != PE; ++PI)
|
||||||
for (SymbolTable::value_const_iterator VI = PI->second.begin(),
|
for (SymbolTable::value_const_iterator VI = PI->second.begin(),
|
||||||
VE = PI->second.end(); VI != VE; ++VI)
|
VE = PI->second.end(); VI != VE; ++VI)
|
||||||
@ -258,7 +258,7 @@ void SlotCalculator::processSymbolTableConstants(const SymbolTable *ST) {
|
|||||||
getOrCreateSlot(TI->second);
|
getOrCreateSlot(TI->second);
|
||||||
|
|
||||||
// Now do the constant values in all planes
|
// Now do the constant values in all planes
|
||||||
for (SymbolTable::plane_const_iterator PI = ST->plane_begin(),
|
for (SymbolTable::plane_const_iterator PI = ST->plane_begin(),
|
||||||
PE = ST->plane_end(); PI != PE; ++PI)
|
PE = ST->plane_end(); PI != PE; ++PI)
|
||||||
for (SymbolTable::value_const_iterator VI = PI->second.begin(),
|
for (SymbolTable::value_const_iterator VI = PI->second.begin(),
|
||||||
VE = PI->second.end(); VI != VE; ++VI)
|
VE = PI->second.end(); VI != VE; ++VI)
|
||||||
@ -294,7 +294,7 @@ void SlotCalculator::incorporateFunction(const Function *F) {
|
|||||||
// before any nonconstant values. This will be turned into the constant
|
// before any nonconstant values. This will be turned into the constant
|
||||||
// pool for the bytecode writer.
|
// pool for the bytecode writer.
|
||||||
//
|
//
|
||||||
|
|
||||||
// Emit all of the constants that are being used by the instructions in
|
// Emit all of the constants that are being used by the instructions in
|
||||||
// the function...
|
// the function...
|
||||||
constant_iterator CI = constant_begin(F);
|
constant_iterator CI = constant_begin(F);
|
||||||
@ -303,10 +303,10 @@ void SlotCalculator::incorporateFunction(const Function *F) {
|
|||||||
this->getOrCreateSlot(*CI);
|
this->getOrCreateSlot(*CI);
|
||||||
++CI;
|
++CI;
|
||||||
}
|
}
|
||||||
|
|
||||||
// If there is a symbol table, it is possible that the user has names for
|
// 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
|
// constants that are not being used. In this case, we will have problems
|
||||||
// if we don't emit the constants now, because otherwise we will get
|
// if we don't emit the constants now, because otherwise we will get
|
||||||
// symbol table references to constants not in the output. Scan for these
|
// symbol table references to constants not in the output. Scan for these
|
||||||
// constants now.
|
// constants now.
|
||||||
//
|
//
|
||||||
@ -380,7 +380,7 @@ void SlotCalculator::purgeFunction() {
|
|||||||
NodeMap.erase(Plane.back()); // Erase from nodemap
|
NodeMap.erase(Plane.back()); // Erase from nodemap
|
||||||
Plane.pop_back(); // Shrink plane
|
Plane.pop_back(); // Shrink plane
|
||||||
}
|
}
|
||||||
|
|
||||||
Table.pop_back(); // Nuke the plane, we don't like it.
|
Table.pop_back(); // Nuke the plane, we don't like it.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -482,7 +482,7 @@ void SlotCalculator::buildCompactionTable(const Function *F) {
|
|||||||
getOrCreateCompactionTableSlot(TI->second);
|
getOrCreateCompactionTableSlot(TI->second);
|
||||||
|
|
||||||
// Now do the constants and global values
|
// Now do the constants and global values
|
||||||
for (SymbolTable::plane_const_iterator PI = ST.plane_begin(),
|
for (SymbolTable::plane_const_iterator PI = ST.plane_begin(),
|
||||||
PE = ST.plane_end(); PI != PE; ++PI)
|
PE = ST.plane_end(); PI != PE; ++PI)
|
||||||
for (SymbolTable::value_const_iterator VI = PI->second.begin(),
|
for (SymbolTable::value_const_iterator VI = PI->second.begin(),
|
||||||
VE = PI->second.end(); VI != VE; ++VI)
|
VE = PI->second.end(); VI != VE; ++VI)
|
||||||
@ -503,14 +503,14 @@ void SlotCalculator::buildCompactionTable(const Function *F) {
|
|||||||
assert(Ty->getTypeID() != Type::LabelTyID);
|
assert(Ty->getTypeID() != Type::LabelTyID);
|
||||||
getOrCreateCompactionTableSlot(Constant::getNullValue(Ty));
|
getOrCreateCompactionTableSlot(Constant::getNullValue(Ty));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Okay, now at this point, we have a legal compaction table. Since we want
|
// Okay, now at this point, we have a legal compaction table. Since we want
|
||||||
// to emit the smallest possible binaries, do not compactify the type plane if
|
// to emit the smallest possible binaries, do not compactify the type plane if
|
||||||
// it will not save us anything. Because we have not yet incorporated the
|
// it will not save us anything. Because we have not yet incorporated the
|
||||||
// function body itself yet, we don't know whether or not it's a good idea to
|
// function body itself yet, we don't know whether or not it's a good idea to
|
||||||
// compactify other planes. We will defer this decision until later.
|
// compactify other planes. We will defer this decision until later.
|
||||||
TypeList &GlobalTypes = Types;
|
TypeList &GlobalTypes = Types;
|
||||||
|
|
||||||
// All of the values types will be scrunched to the start of the types plane
|
// All of the values types will be scrunched to the start of the types plane
|
||||||
// of the global table. Figure out just how many there are.
|
// of the global table. Figure out just how many there are.
|
||||||
assert(!GlobalTypes.empty() && "No global types???");
|
assert(!GlobalTypes.empty() && "No global types???");
|
||||||
@ -530,7 +530,7 @@ void SlotCalculator::buildCompactionTable(const Function *F) {
|
|||||||
std::swap(CompactionTable, TmpCompactionTable);
|
std::swap(CompactionTable, TmpCompactionTable);
|
||||||
TypeList TmpTypes;
|
TypeList TmpTypes;
|
||||||
std::swap(TmpTypes, CompactionTypes);
|
std::swap(TmpTypes, CompactionTypes);
|
||||||
|
|
||||||
// Move each plane back over to the uncompactified plane
|
// Move each plane back over to the uncompactified plane
|
||||||
while (!TmpTypes.empty()) {
|
while (!TmpTypes.empty()) {
|
||||||
const Type *Ty = TmpTypes.back();
|
const Type *Ty = TmpTypes.back();
|
||||||
@ -540,7 +540,7 @@ void SlotCalculator::buildCompactionTable(const Function *F) {
|
|||||||
// Find the global slot number for this type.
|
// Find the global slot number for this type.
|
||||||
int TySlot = getSlot(Ty);
|
int TySlot = getSlot(Ty);
|
||||||
assert(TySlot != -1 && "Type doesn't exist in global table?");
|
assert(TySlot != -1 && "Type doesn't exist in global table?");
|
||||||
|
|
||||||
// Now we know where to put the compaction table plane.
|
// Now we know where to put the compaction table plane.
|
||||||
if (CompactionTable.size() <= unsigned(TySlot))
|
if (CompactionTable.size() <= unsigned(TySlot))
|
||||||
CompactionTable.resize(TySlot+1);
|
CompactionTable.resize(TySlot+1);
|
||||||
@ -575,7 +575,7 @@ void SlotCalculator::pruneCompactionTable() {
|
|||||||
if (GlobalSlot >= Table.size())
|
if (GlobalSlot >= Table.size())
|
||||||
Table.resize(GlobalSlot+1);
|
Table.resize(GlobalSlot+1);
|
||||||
TypePlane &GPlane = Table[GlobalSlot];
|
TypePlane &GPlane = Table[GlobalSlot];
|
||||||
|
|
||||||
unsigned ModLevel = getModuleLevel(ctp);
|
unsigned ModLevel = getModuleLevel(ctp);
|
||||||
unsigned NumFunctionObjs = CPlane.size()-ModLevel;
|
unsigned NumFunctionObjs = CPlane.size()-ModLevel;
|
||||||
|
|
||||||
@ -624,7 +624,7 @@ void SlotCalculator::pruneCompactionTable() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Determine if the compaction table is actually empty. Because the
|
/// Determine if the compaction table is actually empty. Because the
|
||||||
/// compaction table always includes the primitive type planes, we
|
/// compaction table always includes the primitive type planes, we
|
||||||
/// can't just check getCompactionTable().size() because it will never
|
/// can't just check getCompactionTable().size() because it will never
|
||||||
/// be zero. Furthermore, the ModuleLevel factors into whether a given
|
/// be zero. Furthermore, the ModuleLevel factors into whether a given
|
||||||
/// plane is empty or not. This function does the necessary computation
|
/// plane is empty or not. This function does the necessary computation
|
||||||
@ -640,7 +640,7 @@ bool SlotCalculator::CompactionTableIsEmpty() const {
|
|||||||
// If the module level is non-zero then at least the
|
// If the module level is non-zero then at least the
|
||||||
// first element of the plane is valid and therefore not empty.
|
// first element of the plane is valid and therefore not empty.
|
||||||
unsigned End = getModuleLevel(i);
|
unsigned End = getModuleLevel(i);
|
||||||
if (End != 0)
|
if (End != 0)
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -699,8 +699,8 @@ int SlotCalculator::getOrCreateSlot(const Value *V) {
|
|||||||
assert(CompactionNodeMap.empty() &&
|
assert(CompactionNodeMap.empty() &&
|
||||||
"All needed constants should be in the compaction map already!");
|
"All needed constants should be in the compaction map already!");
|
||||||
|
|
||||||
// Do not index the characters that make up constant strings. We emit
|
// Do not index the characters that make up constant strings. We emit
|
||||||
// constant strings as special entities that don't require their
|
// constant strings as special entities that don't require their
|
||||||
// individual characters to be emitted.
|
// individual characters to be emitted.
|
||||||
if (!isa<ConstantArray>(C) || !cast<ConstantArray>(C)->isString()) {
|
if (!isa<ConstantArray>(C) || !cast<ConstantArray>(C)->isString()) {
|
||||||
// This makes sure that if a constant has uses (for example an array of
|
// This makes sure that if a constant has uses (for example an array of
|
||||||
@ -746,7 +746,7 @@ int SlotCalculator::insertValue(const Value *D, bool dontIgnore) {
|
|||||||
return getOrCreateCompactionTableSlot(D);
|
return getOrCreateCompactionTableSlot(D);
|
||||||
}
|
}
|
||||||
|
|
||||||
// If this node does not contribute to a plane, or if the node has a
|
// If this node does not contribute to a plane, or if the node has a
|
||||||
// name and we don't want names, then ignore the silly node... Note that types
|
// name and we don't want names, then ignore the silly node... Note that types
|
||||||
// do need slot numbers so that we can keep track of where other values land.
|
// do need slot numbers so that we can keep track of where other values land.
|
||||||
//
|
//
|
||||||
@ -823,7 +823,7 @@ int SlotCalculator::doInsertValue(const Value *D) {
|
|||||||
} else {
|
} else {
|
||||||
Ty = Typ->getTypeID();
|
Ty = Typ->getTypeID();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Table.size() <= Ty) // Make sure we have the type plane allocated...
|
if (Table.size() <= Ty) // Make sure we have the type plane allocated...
|
||||||
Table.resize(Ty+1, TypePlane());
|
Table.resize(Ty+1, TypePlane());
|
||||||
|
|
||||||
@ -843,10 +843,10 @@ int SlotCalculator::doInsertValue(const Value *D) {
|
|||||||
unsigned DestSlot = NodeMap[D] = Table[Ty].size();
|
unsigned DestSlot = NodeMap[D] = Table[Ty].size();
|
||||||
Table[Ty].push_back(D);
|
Table[Ty].push_back(D);
|
||||||
|
|
||||||
SC_DEBUG(" Inserting value [" << Ty << "] = " << D << " slot=" <<
|
SC_DEBUG(" Inserting value [" << Ty << "] = " << D << " slot=" <<
|
||||||
DestSlot << " [");
|
DestSlot << " [");
|
||||||
// G = Global, C = Constant, T = Type, F = Function, o = other
|
// G = Global, C = Constant, T = Type, F = Function, o = other
|
||||||
SC_DEBUG((isa<GlobalVariable>(D) ? "G" : (isa<Constant>(D) ? "C" :
|
SC_DEBUG((isa<GlobalVariable>(D) ? "G" : (isa<Constant>(D) ? "C" :
|
||||||
(isa<Function>(D) ? "F" : "o"))));
|
(isa<Function>(D) ? "F" : "o"))));
|
||||||
SC_DEBUG("]\n");
|
SC_DEBUG("]\n");
|
||||||
return (int)DestSlot;
|
return (int)DestSlot;
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
//===-- Analysis/SlotCalculator.h - Calculate value slots -------*- C++ -*-===//
|
//===-- Analysis/SlotCalculator.h - Calculate value slots -------*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
// This file was developed by the LLVM research group and is distributed under
|
// This file was developed by the LLVM research group and is distributed under
|
||||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This class calculates the slots that values will land in. This is useful for
|
// This class calculates the slots that values will land in. This is useful for
|
||||||
@ -77,7 +77,7 @@ public:
|
|||||||
SlotCalculator(const Module *M );
|
SlotCalculator(const Module *M );
|
||||||
// Start out in incorp state
|
// 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
|
/// getSlot - Return the slot number of the specified value in it's type
|
||||||
/// plane. This returns < 0 on error!
|
/// plane. This returns < 0 on error!
|
||||||
///
|
///
|
||||||
@ -103,8 +103,8 @@ public:
|
|||||||
return CompactionTypes.size();
|
return CompactionTypes.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned getModuleLevel(unsigned Plane) const {
|
inline unsigned getModuleLevel(unsigned Plane) const {
|
||||||
return Plane < ModuleLevel.size() ? ModuleLevel[Plane] : 0;
|
return Plane < ModuleLevel.size() ? ModuleLevel[Plane] : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the number of types in the type list that are at module level
|
/// Returns the number of types in the type list that are at module level
|
||||||
@ -113,7 +113,7 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
TypePlane &getPlane(unsigned Plane);
|
TypePlane &getPlane(unsigned Plane);
|
||||||
TypeList& getTypes() {
|
TypeList& getTypes() {
|
||||||
if (!CompactionTypes.empty())
|
if (!CompactionTypes.empty())
|
||||||
return CompactionTypes;
|
return CompactionTypes;
|
||||||
return Types;
|
return Types;
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
//===-- Internal/SlotTable.h - Type/Value Slot Holder -----------*- C++ -*-===//
|
//===-- Internal/SlotTable.h - Type/Value Slot Holder -----------*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
// This file was developed by Reid Spencer and is distributed under
|
// This file was developed by Reid Spencer and is distributed under
|
||||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This file declares the SlotTable class for type plane numbering.
|
// This file declares the SlotTable class for type plane numbering.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
#ifndef LLVM_INTERNAL_SLOTTABLE_H
|
#ifndef LLVM_INTERNAL_SLOTTABLE_H
|
||||||
@ -28,10 +28,10 @@ class SymbolTable;
|
|||||||
class ConstantArray;
|
class ConstantArray;
|
||||||
|
|
||||||
/// This class is the common abstract data type for both the SlotMachine and
|
/// This class is the common abstract data type for both the SlotMachine and
|
||||||
/// the SlotCalculator. It provides the two-way mapping between Values and
|
/// the SlotCalculator. It provides the two-way mapping between Values and
|
||||||
/// Slots as well as the two-way mapping between Types and Slots. For Values,
|
/// Slots as well as the two-way mapping between Types and Slots. For Values,
|
||||||
/// the slot number can be extracted by simply using the getSlot()
|
/// the slot number can be extracted by simply using the getSlot()
|
||||||
/// method and passing in the Value. For Types, it is the same.
|
/// method and passing in the Value. For Types, it is the same.
|
||||||
/// @brief Abstract data type for slot numbers.
|
/// @brief Abstract data type for slot numbers.
|
||||||
class SlotTable
|
class SlotTable
|
||||||
{
|
{
|
||||||
@ -39,7 +39,7 @@ class SlotTable
|
|||||||
/// @{
|
/// @{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
/// This type is used throughout the code to make it clear that
|
/// This type is used throughout the code to make it clear that
|
||||||
/// an unsigned value refers to a Slot number and not something else.
|
/// an unsigned value refers to a Slot number and not something else.
|
||||||
/// @brief Type slot number identification type.
|
/// @brief Type slot number identification type.
|
||||||
typedef unsigned SlotNum;
|
typedef unsigned SlotNum;
|
||||||
@ -56,13 +56,13 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
/// @brief A single plane of Values. Intended index is slot number.
|
/// @brief A single plane of Values. Intended index is slot number.
|
||||||
typedef std::vector<const Value*> ValuePlane;
|
typedef std::vector<const Value*> ValuePlane;
|
||||||
|
|
||||||
/// @brief A table of Values. Intended index is Type::TypeID.
|
/// @brief A table of Values. Intended index is Type::TypeID.
|
||||||
typedef std::vector<ValuePlane> ValueTable;
|
typedef std::vector<ValuePlane> ValueTable;
|
||||||
|
|
||||||
/// @brief A map of values to slot numbers.
|
/// @brief A map of values to slot numbers.
|
||||||
typedef std::map<const Value*,SlotNum> ValueMap;
|
typedef std::map<const Value*,SlotNum> ValueMap;
|
||||||
|
|
||||||
/// @brief A single plane of Types. Intended index is slot number.
|
/// @brief A single plane of Types. Intended index is slot number.
|
||||||
typedef std::vector<const Type*> TypePlane;
|
typedef std::vector<const Type*> TypePlane;
|
||||||
@ -80,7 +80,7 @@ public:
|
|||||||
/// SlotTable will need the primitive types. If you don't need them, pass
|
/// SlotTable will need the primitive types. If you don't need them, pass
|
||||||
/// in true.
|
/// in true.
|
||||||
/// @brief Default Constructor
|
/// @brief Default Constructor
|
||||||
explicit SlotTable(
|
explicit SlotTable(
|
||||||
bool dont_insert_primitives = false ///< Control insertion of primitives.
|
bool dont_insert_primitives = false ///< Control insertion of primitives.
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -169,11 +169,11 @@ private:
|
|||||||
ValueTable vTable;
|
ValueTable vTable;
|
||||||
|
|
||||||
/// A map of Values to unsigned integer. This allows for efficient lookup of
|
/// A map of Values to unsigned integer. This allows for efficient lookup of
|
||||||
/// A Value's slot number in its type plane.
|
/// A Value's slot number in its type plane.
|
||||||
ValueMap vMap;
|
ValueMap vMap;
|
||||||
|
|
||||||
/// A one dimensional vector of Types indexed by slot number. Types are
|
/// A one dimensional vector of Types indexed by slot number. Types are
|
||||||
/// handled separately because they are not Values.
|
/// handled separately because they are not Values.
|
||||||
TypePlane tPlane;
|
TypePlane tPlane;
|
||||||
|
|
||||||
/// A map of Types to unsigned integer. This allows for efficient lookup of
|
/// A map of Types to unsigned integer. This allows for efficient lookup of
|
||||||
@ -186,6 +186,6 @@ private:
|
|||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
// vim: sw=2
|
// vim: sw=2
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
//===-- Writer.cpp - Library for writing LLVM bytecode files --------------===//
|
//===-- Writer.cpp - Library for writing LLVM bytecode files --------------===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
// This file was developed by the LLVM research group and is distributed under
|
// This file was developed by the LLVM research group and is distributed under
|
||||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This library implements the functionality defined in llvm/Bytecode/Writer.h
|
// This library implements the functionality defined in llvm/Bytecode/Writer.h
|
||||||
@ -40,7 +40,7 @@ const unsigned BCVersionNum = 5;
|
|||||||
|
|
||||||
static RegisterPass<WriteBytecodePass> X("emitbytecode", "Bytecode Writer");
|
static RegisterPass<WriteBytecodePass> X("emitbytecode", "Bytecode Writer");
|
||||||
|
|
||||||
static Statistic<>
|
static Statistic<>
|
||||||
BytesWritten("bytecodewriter", "Number of bytecode bytes written");
|
BytesWritten("bytecodewriter", "Number of bytecode bytes written");
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
@ -48,11 +48,11 @@ BytesWritten("bytecodewriter", "Number of bytecode bytes written");
|
|||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
// output - If a position is specified, it must be in the valid portion of the
|
// output - If a position is specified, it must be in the valid portion of the
|
||||||
// string... note that this should be inlined always so only the relevant IF
|
// string... note that this should be inlined always so only the relevant IF
|
||||||
// body should be included.
|
// body should be included.
|
||||||
inline void BytecodeWriter::output(unsigned i, int pos) {
|
inline void BytecodeWriter::output(unsigned i, int pos) {
|
||||||
if (pos == -1) { // Be endian clean, little endian is our friend
|
if (pos == -1) { // Be endian clean, little endian is our friend
|
||||||
Out.push_back((unsigned char)i);
|
Out.push_back((unsigned char)i);
|
||||||
Out.push_back((unsigned char)(i >> 8));
|
Out.push_back((unsigned char)(i >> 8));
|
||||||
Out.push_back((unsigned char)(i >> 16));
|
Out.push_back((unsigned char)(i >> 16));
|
||||||
Out.push_back((unsigned char)(i >> 24));
|
Out.push_back((unsigned char)(i >> 24));
|
||||||
@ -71,15 +71,15 @@ inline void BytecodeWriter::output(int i) {
|
|||||||
/// output_vbr - Output an unsigned value, by using the least number of bytes
|
/// output_vbr - Output an unsigned value, by using the least number of bytes
|
||||||
/// possible. This is useful because many of our "infinite" values are really
|
/// possible. This is useful because many of our "infinite" values are really
|
||||||
/// very small most of the time; but can be large a few times.
|
/// very small most of the time; but can be large a few times.
|
||||||
/// Data format used: If you read a byte with the high bit set, use the low
|
/// Data format used: If you read a byte with the high bit set, use the low
|
||||||
/// seven bits as data and then read another byte.
|
/// seven bits as data and then read another byte.
|
||||||
inline void BytecodeWriter::output_vbr(uint64_t i) {
|
inline void BytecodeWriter::output_vbr(uint64_t i) {
|
||||||
while (1) {
|
while (1) {
|
||||||
if (i < 0x80) { // done?
|
if (i < 0x80) { // done?
|
||||||
Out.push_back((unsigned char)i); // We know the high bit is clear...
|
Out.push_back((unsigned char)i); // We know the high bit is clear...
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nope, we are bigger than a character, output the next 7 bits and set the
|
// Nope, we are bigger than a character, output the next 7 bits and set the
|
||||||
// high bit to say that there is more coming...
|
// high bit to say that there is more coming...
|
||||||
Out.push_back(0x80 | ((unsigned char)i & 0x7F));
|
Out.push_back(0x80 | ((unsigned char)i & 0x7F));
|
||||||
@ -93,7 +93,7 @@ inline void BytecodeWriter::output_vbr(unsigned i) {
|
|||||||
Out.push_back((unsigned char)i); // We know the high bit is clear...
|
Out.push_back((unsigned char)i); // We know the high bit is clear...
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Nope, we are bigger than a character, output the next 7 bits and set the
|
// Nope, we are bigger than a character, output the next 7 bits and set the
|
||||||
// high bit to say that there is more coming...
|
// high bit to say that there is more coming...
|
||||||
Out.push_back(0x80 | ((unsigned char)i & 0x7F));
|
Out.push_back(0x80 | ((unsigned char)i & 0x7F));
|
||||||
@ -111,7 +111,7 @@ inline void BytecodeWriter::output_typeid(unsigned i) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline void BytecodeWriter::output_vbr(int64_t i) {
|
inline void BytecodeWriter::output_vbr(int64_t i) {
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
output_vbr(((uint64_t)(-i) << 1) | 1); // Set low order sign bit...
|
output_vbr(((uint64_t)(-i) << 1) | 1); // Set low order sign bit...
|
||||||
else
|
else
|
||||||
output_vbr((uint64_t)i << 1); // Low order bit is clear.
|
output_vbr((uint64_t)i << 1); // Low order bit is clear.
|
||||||
@ -119,7 +119,7 @@ inline void BytecodeWriter::output_vbr(int64_t i) {
|
|||||||
|
|
||||||
|
|
||||||
inline void BytecodeWriter::output_vbr(int i) {
|
inline void BytecodeWriter::output_vbr(int i) {
|
||||||
if (i < 0)
|
if (i < 0)
|
||||||
output_vbr(((unsigned)(-i) << 1) | 1); // Set low order sign bit...
|
output_vbr(((unsigned)(-i) << 1) | 1); // Set low order sign bit...
|
||||||
else
|
else
|
||||||
output_vbr((unsigned)i << 1); // Low order bit is clear.
|
output_vbr((unsigned)i << 1); // Low order bit is clear.
|
||||||
@ -168,7 +168,7 @@ inline void BytecodeWriter::output_double(double& DoubleVal) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter& w,
|
inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter& w,
|
||||||
bool elideIfEmpty, bool hasLongFormat )
|
bool elideIfEmpty, bool hasLongFormat )
|
||||||
: Id(ID), Writer(w), ElideIfEmpty(elideIfEmpty), HasLongFormat(hasLongFormat){
|
: Id(ID), Writer(w), ElideIfEmpty(elideIfEmpty), HasLongFormat(hasLongFormat){
|
||||||
|
|
||||||
if (HasLongFormat) {
|
if (HasLongFormat) {
|
||||||
@ -181,7 +181,7 @@ inline BytecodeBlock::BytecodeBlock(unsigned ID, BytecodeWriter& w,
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline BytecodeBlock::~BytecodeBlock() { // Do backpatch when block goes out
|
inline BytecodeBlock::~BytecodeBlock() { // Do backpatch when block goes out
|
||||||
// of scope...
|
// of scope...
|
||||||
if (Loc == Writer.size() && ElideIfEmpty) {
|
if (Loc == Writer.size() && ElideIfEmpty) {
|
||||||
// If the block is empty, and we are allowed to, do not emit the block at
|
// If the block is empty, and we are allowed to, do not emit the block at
|
||||||
// all!
|
// all!
|
||||||
@ -201,7 +201,7 @@ inline BytecodeBlock::~BytecodeBlock() { // Do backpatch when block goes out
|
|||||||
|
|
||||||
void BytecodeWriter::outputType(const Type *T) {
|
void BytecodeWriter::outputType(const Type *T) {
|
||||||
output_vbr((unsigned)T->getTypeID());
|
output_vbr((unsigned)T->getTypeID());
|
||||||
|
|
||||||
// That's all there is to handling primitive types...
|
// That's all there is to handling primitive types...
|
||||||
if (T->isPrimitiveType()) {
|
if (T->isPrimitiveType()) {
|
||||||
return; // We might do this if we alias a prim type: %x = type int
|
return; // We might do this if we alias a prim type: %x = type int
|
||||||
@ -291,14 +291,14 @@ void BytecodeWriter::outputConstant(const Constant *CPV) {
|
|||||||
|
|
||||||
// We must check for a ConstantExpr before switching by type because
|
// We must check for a ConstantExpr before switching by type because
|
||||||
// a ConstantExpr can be of any type, and has no explicit value.
|
// a ConstantExpr can be of any type, and has no explicit value.
|
||||||
//
|
//
|
||||||
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
|
if (const ConstantExpr *CE = dyn_cast<ConstantExpr>(CPV)) {
|
||||||
// FIXME: Encoding of constant exprs could be much more compact!
|
// FIXME: Encoding of constant exprs could be much more compact!
|
||||||
assert(CE->getNumOperands() > 0 && "ConstantExpr with 0 operands");
|
assert(CE->getNumOperands() > 0 && "ConstantExpr with 0 operands");
|
||||||
assert(CE->getNumOperands() != 1 || CE->getOpcode() == Instruction::Cast);
|
assert(CE->getNumOperands() != 1 || CE->getOpcode() == Instruction::Cast);
|
||||||
output_vbr(1+CE->getNumOperands()); // flags as an expr
|
output_vbr(1+CE->getNumOperands()); // flags as an expr
|
||||||
output_vbr(CE->getOpcode()); // flags as an expr
|
output_vbr(CE->getOpcode()); // flags as an expr
|
||||||
|
|
||||||
for (User::const_op_iterator OI = CE->op_begin(); OI != CE->op_end(); ++OI){
|
for (User::const_op_iterator OI = CE->op_begin(); OI != CE->op_end(); ++OI){
|
||||||
int Slot = Table.getSlot(*OI);
|
int Slot = Table.getSlot(*OI);
|
||||||
assert(Slot != -1 && "Unknown constant used in ConstantExpr!!");
|
assert(Slot != -1 && "Unknown constant used in ConstantExpr!!");
|
||||||
@ -313,7 +313,7 @@ void BytecodeWriter::outputConstant(const Constant *CPV) {
|
|||||||
} else {
|
} else {
|
||||||
output_vbr(0U); // flag as not a ConstantExpr
|
output_vbr(0U); // flag as not a ConstantExpr
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (CPV->getType()->getTypeID()) {
|
switch (CPV->getType()->getTypeID()) {
|
||||||
case Type::BoolTyID: // Boolean Types
|
case Type::BoolTyID: // Boolean Types
|
||||||
if (cast<ConstantBool>(CPV)->getValue())
|
if (cast<ConstantBool>(CPV)->getValue())
|
||||||
@ -385,7 +385,7 @@ void BytecodeWriter::outputConstant(const Constant *CPV) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case Type::VoidTyID:
|
case Type::VoidTyID:
|
||||||
case Type::LabelTyID:
|
case Type::LabelTyID:
|
||||||
default:
|
default:
|
||||||
std::cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to serialize"
|
std::cerr << __FILE__ << ":" << __LINE__ << ": Don't know how to serialize"
|
||||||
@ -404,14 +404,14 @@ void BytecodeWriter::outputConstantStrings() {
|
|||||||
// the 'void' type plane.
|
// the 'void' type plane.
|
||||||
output_vbr(unsigned(E-I));
|
output_vbr(unsigned(E-I));
|
||||||
output_typeid(Type::VoidTyID);
|
output_typeid(Type::VoidTyID);
|
||||||
|
|
||||||
// Emit all of the strings.
|
// Emit all of the strings.
|
||||||
for (I = Table.string_begin(); I != E; ++I) {
|
for (I = Table.string_begin(); I != E; ++I) {
|
||||||
const ConstantArray *Str = *I;
|
const ConstantArray *Str = *I;
|
||||||
int Slot = Table.getSlot(Str->getType());
|
int Slot = Table.getSlot(Str->getType());
|
||||||
assert(Slot != -1 && "Constant string of unknown type?");
|
assert(Slot != -1 && "Constant string of unknown type?");
|
||||||
output_typeid((unsigned)Slot);
|
output_typeid((unsigned)Slot);
|
||||||
|
|
||||||
// Now that we emitted the type (which indicates the size of the string),
|
// Now that we emitted the type (which indicates the size of the string),
|
||||||
// emit all of the characters.
|
// emit all of the characters.
|
||||||
std::string Val = Str->getAsString();
|
std::string Val = Str->getAsString();
|
||||||
@ -444,7 +444,7 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
|
|||||||
if (!isa<GetElementPtrInst>(&I)) {
|
if (!isa<GetElementPtrInst>(&I)) {
|
||||||
for (unsigned i = 0; i < NumArgs; ++i) {
|
for (unsigned i = 0; i < NumArgs; ++i) {
|
||||||
int Slot = Table.getSlot(I->getOperand(i));
|
int Slot = Table.getSlot(I->getOperand(i));
|
||||||
assert(Slot >= 0 && "No slot number for value!?!?");
|
assert(Slot >= 0 && "No slot number for value!?!?");
|
||||||
output_vbr((unsigned)Slot);
|
output_vbr((unsigned)Slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -460,7 +460,7 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
int Slot = Table.getSlot(I->getOperand(0));
|
int Slot = Table.getSlot(I->getOperand(0));
|
||||||
assert(Slot >= 0 && "No slot number for value!?!?");
|
assert(Slot >= 0 && "No slot number for value!?!?");
|
||||||
output_vbr(unsigned(Slot));
|
output_vbr(unsigned(Slot));
|
||||||
|
|
||||||
// We need to encode the type of sequential type indices into their slot #
|
// We need to encode the type of sequential type indices into their slot #
|
||||||
@ -468,8 +468,8 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
|
|||||||
for (gep_type_iterator TI = gep_type_begin(I), E = gep_type_end(I);
|
for (gep_type_iterator TI = gep_type_begin(I), E = gep_type_end(I);
|
||||||
Idx != NumArgs; ++TI, ++Idx) {
|
Idx != NumArgs; ++TI, ++Idx) {
|
||||||
Slot = Table.getSlot(I->getOperand(Idx));
|
Slot = Table.getSlot(I->getOperand(Idx));
|
||||||
assert(Slot >= 0 && "No slot number for value!?!?");
|
assert(Slot >= 0 && "No slot number for value!?!?");
|
||||||
|
|
||||||
if (isa<SequentialType>(*TI)) {
|
if (isa<SequentialType>(*TI)) {
|
||||||
unsigned IdxId;
|
unsigned IdxId;
|
||||||
switch (I->getOperand(Idx)->getType()->getTypeID()) {
|
switch (I->getOperand(Idx)->getType()->getTypeID()) {
|
||||||
@ -496,10 +496,10 @@ void BytecodeWriter::outputInstructionFormat0(const Instruction *I,
|
|||||||
//
|
//
|
||||||
// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
|
// Format: [opcode] [type] [numargs] [arg0] [arg1] ... [arg<numargs-1>]
|
||||||
//
|
//
|
||||||
void BytecodeWriter::outputInstrVarArgsCall(const Instruction *I,
|
void BytecodeWriter::outputInstrVarArgsCall(const Instruction *I,
|
||||||
unsigned Opcode,
|
unsigned Opcode,
|
||||||
const SlotCalculator &Table,
|
const SlotCalculator &Table,
|
||||||
unsigned Type) {
|
unsigned Type) {
|
||||||
assert(isa<CallInst>(I) || isa<InvokeInst>(I));
|
assert(isa<CallInst>(I) || isa<InvokeInst>(I));
|
||||||
// Opcode must have top two bits clear...
|
// Opcode must have top two bits clear...
|
||||||
output_vbr(Opcode << 2); // Instruction Opcode ID
|
output_vbr(Opcode << 2); // Instruction Opcode ID
|
||||||
@ -526,19 +526,19 @@ void BytecodeWriter::outputInstrVarArgsCall(const Instruction *I,
|
|||||||
// instruction. Just emit the slot # now.
|
// instruction. Just emit the slot # now.
|
||||||
for (unsigned i = 0; i != NumFixedOperands; ++i) {
|
for (unsigned i = 0; i != NumFixedOperands; ++i) {
|
||||||
int Slot = Table.getSlot(I->getOperand(i));
|
int Slot = Table.getSlot(I->getOperand(i));
|
||||||
assert(Slot >= 0 && "No slot number for value!?!?");
|
assert(Slot >= 0 && "No slot number for value!?!?");
|
||||||
output_vbr((unsigned)Slot);
|
output_vbr((unsigned)Slot);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned i = NumFixedOperands, e = I->getNumOperands(); i != e; ++i) {
|
for (unsigned i = NumFixedOperands, e = I->getNumOperands(); i != e; ++i) {
|
||||||
// Output Arg Type ID
|
// Output Arg Type ID
|
||||||
int Slot = Table.getSlot(I->getOperand(i)->getType());
|
int Slot = Table.getSlot(I->getOperand(i)->getType());
|
||||||
assert(Slot >= 0 && "No slot number for value!?!?");
|
assert(Slot >= 0 && "No slot number for value!?!?");
|
||||||
output_typeid((unsigned)Slot);
|
output_typeid((unsigned)Slot);
|
||||||
|
|
||||||
// Output arg ID itself
|
// Output arg ID itself
|
||||||
Slot = Table.getSlot(I->getOperand(i));
|
Slot = Table.getSlot(I->getOperand(i));
|
||||||
assert(Slot >= 0 && "No slot number for value!?!?");
|
assert(Slot >= 0 && "No slot number for value!?!?");
|
||||||
output_vbr((unsigned)Slot);
|
output_vbr((unsigned)Slot);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -547,10 +547,10 @@ void BytecodeWriter::outputInstrVarArgsCall(const Instruction *I,
|
|||||||
// outputInstructionFormat1 - Output one operand instructions, knowing that no
|
// outputInstructionFormat1 - Output one operand instructions, knowing that no
|
||||||
// operand index is >= 2^12.
|
// operand index is >= 2^12.
|
||||||
//
|
//
|
||||||
inline void BytecodeWriter::outputInstructionFormat1(const Instruction *I,
|
inline void BytecodeWriter::outputInstructionFormat1(const Instruction *I,
|
||||||
unsigned Opcode,
|
unsigned Opcode,
|
||||||
unsigned *Slots,
|
unsigned *Slots,
|
||||||
unsigned Type) {
|
unsigned Type) {
|
||||||
// bits Instruction format:
|
// bits Instruction format:
|
||||||
// --------------------------
|
// --------------------------
|
||||||
// 01-00: Opcode type, fixed to 1.
|
// 01-00: Opcode type, fixed to 1.
|
||||||
@ -565,17 +565,17 @@ inline void BytecodeWriter::outputInstructionFormat1(const Instruction *I,
|
|||||||
// outputInstructionFormat2 - Output two operand instructions, knowing that no
|
// outputInstructionFormat2 - Output two operand instructions, knowing that no
|
||||||
// operand index is >= 2^8.
|
// operand index is >= 2^8.
|
||||||
//
|
//
|
||||||
inline void BytecodeWriter::outputInstructionFormat2(const Instruction *I,
|
inline void BytecodeWriter::outputInstructionFormat2(const Instruction *I,
|
||||||
unsigned Opcode,
|
unsigned Opcode,
|
||||||
unsigned *Slots,
|
unsigned *Slots,
|
||||||
unsigned Type) {
|
unsigned Type) {
|
||||||
// bits Instruction format:
|
// bits Instruction format:
|
||||||
// --------------------------
|
// --------------------------
|
||||||
// 01-00: Opcode type, fixed to 2.
|
// 01-00: Opcode type, fixed to 2.
|
||||||
// 07-02: Opcode
|
// 07-02: Opcode
|
||||||
// 15-08: Resulting type plane
|
// 15-08: Resulting type plane
|
||||||
// 23-16: Operand #1
|
// 23-16: Operand #1
|
||||||
// 31-24: Operand #2
|
// 31-24: Operand #2
|
||||||
//
|
//
|
||||||
output(2 | (Opcode << 2) | (Type << 8) | (Slots[0] << 16) | (Slots[1] << 24));
|
output(2 | (Opcode << 2) | (Type << 8) | (Slots[0] << 16) | (Slots[1] << 24));
|
||||||
}
|
}
|
||||||
@ -584,10 +584,10 @@ inline void BytecodeWriter::outputInstructionFormat2(const Instruction *I,
|
|||||||
// outputInstructionFormat3 - Output three operand instructions, knowing that no
|
// outputInstructionFormat3 - Output three operand instructions, knowing that no
|
||||||
// operand index is >= 2^6.
|
// operand index is >= 2^6.
|
||||||
//
|
//
|
||||||
inline void BytecodeWriter::outputInstructionFormat3(const Instruction *I,
|
inline void BytecodeWriter::outputInstructionFormat3(const Instruction *I,
|
||||||
unsigned Opcode,
|
unsigned Opcode,
|
||||||
unsigned *Slots,
|
unsigned *Slots,
|
||||||
unsigned Type) {
|
unsigned Type) {
|
||||||
// bits Instruction format:
|
// bits Instruction format:
|
||||||
// --------------------------
|
// --------------------------
|
||||||
// 01-00: Opcode type, fixed to 3.
|
// 01-00: Opcode type, fixed to 3.
|
||||||
@ -616,7 +616,7 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
|
|||||||
// the type of the first parameter, as opposed to the type of the instruction
|
// the type of the first parameter, as opposed to the type of the instruction
|
||||||
// (for example, with setcc, we always know it returns bool, but the type of
|
// (for example, with setcc, we always know it returns bool, but the type of
|
||||||
// the first param is actually interesting). But if we have no arguments
|
// the first param is actually interesting). But if we have no arguments
|
||||||
// we take the type of the instruction itself.
|
// we take the type of the instruction itself.
|
||||||
//
|
//
|
||||||
const Type *Ty;
|
const Type *Ty;
|
||||||
switch (I.getOpcode()) {
|
switch (I.getOpcode()) {
|
||||||
@ -661,7 +661,7 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
|
|||||||
//
|
//
|
||||||
unsigned MaxOpSlot = Type;
|
unsigned MaxOpSlot = Type;
|
||||||
unsigned Slots[3]; Slots[0] = (1 << 12)-1; // Marker to signify 0 operands
|
unsigned Slots[3]; Slots[0] = (1 << 12)-1; // Marker to signify 0 operands
|
||||||
|
|
||||||
for (unsigned i = 0; i != NumOperands; ++i) {
|
for (unsigned i = 0; i != NumOperands; ++i) {
|
||||||
int slot = Table.getSlot(I.getOperand(i));
|
int slot = Table.getSlot(I.getOperand(i));
|
||||||
assert(slot != -1 && "Broken bytecode!");
|
assert(slot != -1 && "Broken bytecode!");
|
||||||
@ -742,7 +742,7 @@ void BytecodeWriter::outputInstruction(const Instruction &I) {
|
|||||||
//=== Block Output ===//
|
//=== Block Output ===//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
BytecodeWriter::BytecodeWriter(std::vector<unsigned char> &o, const Module *M)
|
BytecodeWriter::BytecodeWriter(std::vector<unsigned char> &o, const Module *M)
|
||||||
: Out(o), Table(M) {
|
: Out(o), Table(M) {
|
||||||
|
|
||||||
// Emit the signature...
|
// Emit the signature...
|
||||||
@ -758,9 +758,9 @@ BytecodeWriter::BytecodeWriter(std::vector<unsigned char> &o, const Module *M)
|
|||||||
bool hasNoPointerSize = M->getPointerSize() == Module::AnyPointerSize;
|
bool hasNoPointerSize = M->getPointerSize() == Module::AnyPointerSize;
|
||||||
|
|
||||||
// Output the version identifier and other information.
|
// Output the version identifier and other information.
|
||||||
unsigned Version = (BCVersionNum << 4) |
|
unsigned Version = (BCVersionNum << 4) |
|
||||||
(unsigned)isBigEndian | (hasLongPointers << 1) |
|
(unsigned)isBigEndian | (hasLongPointers << 1) |
|
||||||
(hasNoEndianness << 2) |
|
(hasNoEndianness << 2) |
|
||||||
(hasNoPointerSize << 3);
|
(hasNoPointerSize << 3);
|
||||||
output_vbr(Version);
|
output_vbr(Version);
|
||||||
|
|
||||||
@ -794,7 +794,7 @@ void BytecodeWriter::outputTypes(unsigned TypeNum) {
|
|||||||
assert(TypeNum <= Types.size() && "Invalid TypeNo index");
|
assert(TypeNum <= Types.size() && "Invalid TypeNo index");
|
||||||
|
|
||||||
unsigned NumEntries = Types.size() - TypeNum;
|
unsigned NumEntries = Types.size() - TypeNum;
|
||||||
|
|
||||||
// Output type header: [num entries]
|
// Output type header: [num entries]
|
||||||
output_vbr(NumEntries);
|
output_vbr(NumEntries);
|
||||||
|
|
||||||
@ -804,11 +804,11 @@ void BytecodeWriter::outputTypes(unsigned TypeNum) {
|
|||||||
|
|
||||||
// Helper function for outputConstants().
|
// Helper function for outputConstants().
|
||||||
// Writes out all the constants in the plane Plane starting at entry StartNo.
|
// Writes out all the constants in the plane Plane starting at entry StartNo.
|
||||||
//
|
//
|
||||||
void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*>
|
void BytecodeWriter::outputConstantsInPlane(const std::vector<const Value*>
|
||||||
&Plane, unsigned StartNo) {
|
&Plane, unsigned StartNo) {
|
||||||
unsigned ValNo = StartNo;
|
unsigned ValNo = StartNo;
|
||||||
|
|
||||||
// Scan through and ignore function arguments, global values, and constant
|
// Scan through and ignore function arguments, global values, and constant
|
||||||
// strings.
|
// strings.
|
||||||
for (; ValNo < Plane.size() &&
|
for (; ValNo < Plane.size() &&
|
||||||
@ -866,13 +866,13 @@ void BytecodeWriter::outputConstants(bool isFunction) {
|
|||||||
unsigned ValNo = 0;
|
unsigned ValNo = 0;
|
||||||
if (isFunction) // Don't re-emit module constants
|
if (isFunction) // Don't re-emit module constants
|
||||||
ValNo += Table.getModuleLevel(pno);
|
ValNo += Table.getModuleLevel(pno);
|
||||||
|
|
||||||
if (hasNullValue(pno)) {
|
if (hasNullValue(pno)) {
|
||||||
// Skip zero initializer
|
// Skip zero initializer
|
||||||
if (ValNo == 0)
|
if (ValNo == 0)
|
||||||
ValNo = 1;
|
ValNo = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write out constants in the plane
|
// Write out constants in the plane
|
||||||
outputConstantsInPlane(Plane, ValNo);
|
outputConstantsInPlane(Plane, ValNo);
|
||||||
}
|
}
|
||||||
@ -892,7 +892,7 @@ static unsigned getEncodedLinkage(const GlobalValue *GV) {
|
|||||||
|
|
||||||
void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
|
void BytecodeWriter::outputModuleInfoBlock(const Module *M) {
|
||||||
BytecodeBlock ModuleInfoBlock(BytecodeFormat::ModuleGlobalInfoBlockID, *this);
|
BytecodeBlock ModuleInfoBlock(BytecodeFormat::ModuleGlobalInfoBlockID, *this);
|
||||||
|
|
||||||
// Output the types for the global variables in the module...
|
// Output the types for the global variables in the module...
|
||||||
for (Module::const_global_iterator I = M->global_begin(), End = M->global_end(); I != End;++I) {
|
for (Module::const_global_iterator I = M->global_begin(), End = M->global_end(); I != End;++I) {
|
||||||
int Slot = Table.getSlot(I->getType());
|
int Slot = Table.getSlot(I->getType());
|
||||||
@ -962,13 +962,13 @@ void BytecodeWriter::outputFunction(const Function *F) {
|
|||||||
// Otherwise, emit the compaction table.
|
// Otherwise, emit the compaction table.
|
||||||
outputCompactionTable();
|
outputCompactionTable();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Output all of the instructions in the body of the function
|
// Output all of the instructions in the body of the function
|
||||||
outputInstructions(F);
|
outputInstructions(F);
|
||||||
|
|
||||||
// If needed, output the symbol table for the function...
|
// If needed, output the symbol table for the function...
|
||||||
outputSymbolTable(F->getSymbolTable());
|
outputSymbolTable(F->getSymbolTable());
|
||||||
|
|
||||||
Table.purgeFunction();
|
Table.purgeFunction();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1029,11 +1029,11 @@ void BytecodeWriter::outputCompactionTable() {
|
|||||||
// Avoid writing the compaction table at all if there is no content.
|
// Avoid writing the compaction table at all if there is no content.
|
||||||
if (Table.getCompactionTypes().size() >= Type::FirstDerivedTyID ||
|
if (Table.getCompactionTypes().size() >= Type::FirstDerivedTyID ||
|
||||||
(!Table.CompactionTableIsEmpty())) {
|
(!Table.CompactionTableIsEmpty())) {
|
||||||
BytecodeBlock CTB(BytecodeFormat::CompactionTableBlockID, *this,
|
BytecodeBlock CTB(BytecodeFormat::CompactionTableBlockID, *this,
|
||||||
true/*ElideIfEmpty*/);
|
true/*ElideIfEmpty*/);
|
||||||
const std::vector<std::vector<const Value*> > &CT =
|
const std::vector<std::vector<const Value*> > &CT =
|
||||||
Table.getCompactionTable();
|
Table.getCompactionTable();
|
||||||
|
|
||||||
// First things first, emit the type compaction table if there is one.
|
// First things first, emit the type compaction table if there is one.
|
||||||
outputCompactionTypes(Type::FirstDerivedTyID);
|
outputCompactionTypes(Type::FirstDerivedTyID);
|
||||||
|
|
||||||
@ -1050,7 +1050,7 @@ void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) {
|
|||||||
BytecodeBlock SymTabBlock(BytecodeFormat::SymbolTableBlockID, *this,
|
BytecodeBlock SymTabBlock(BytecodeFormat::SymbolTableBlockID, *this,
|
||||||
true/*ElideIfEmpty*/);
|
true/*ElideIfEmpty*/);
|
||||||
|
|
||||||
// Write the number of types
|
// Write the number of types
|
||||||
output_vbr(MST.num_types());
|
output_vbr(MST.num_types());
|
||||||
|
|
||||||
// Write each of the types
|
// Write each of the types
|
||||||
@ -1058,16 +1058,16 @@ void BytecodeWriter::outputSymbolTable(const SymbolTable &MST) {
|
|||||||
TE = MST.type_end(); TI != TE; ++TI ) {
|
TE = MST.type_end(); TI != TE; ++TI ) {
|
||||||
// Symtab entry:[def slot #][name]
|
// Symtab entry:[def slot #][name]
|
||||||
output_typeid((unsigned)Table.getSlot(TI->second));
|
output_typeid((unsigned)Table.getSlot(TI->second));
|
||||||
output(TI->first);
|
output(TI->first);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now do each of the type planes in order.
|
// Now do each of the type planes in order.
|
||||||
for (SymbolTable::plane_const_iterator PI = MST.plane_begin(),
|
for (SymbolTable::plane_const_iterator PI = MST.plane_begin(),
|
||||||
PE = MST.plane_end(); PI != PE; ++PI) {
|
PE = MST.plane_end(); PI != PE; ++PI) {
|
||||||
SymbolTable::value_const_iterator I = MST.value_begin(PI->first);
|
SymbolTable::value_const_iterator I = MST.value_begin(PI->first);
|
||||||
SymbolTable::value_const_iterator End = MST.value_end(PI->first);
|
SymbolTable::value_const_iterator End = MST.value_end(PI->first);
|
||||||
int Slot;
|
int Slot;
|
||||||
|
|
||||||
if (I == End) continue; // Don't mess with an absent type...
|
if (I == End) continue; // Don't mess with an absent type...
|
||||||
|
|
||||||
// Write the number of values in this plane
|
// Write the number of values in this plane
|
||||||
@ -1116,7 +1116,7 @@ void llvm::WriteBytecodeToFile(const Module *M, std::ostream &Out,
|
|||||||
|
|
||||||
// We signal compression by using an alternate magic number for the
|
// We signal compression by using an alternate magic number for the
|
||||||
// file. The compressed bytecode file's magic number is "llvc" instead
|
// file. The compressed bytecode file's magic number is "llvc" instead
|
||||||
// of "llvm".
|
// of "llvm".
|
||||||
char compressed_magic[4];
|
char compressed_magic[4];
|
||||||
compressed_magic[0] = 'l';
|
compressed_magic[0] = 'l';
|
||||||
compressed_magic[1] = 'l';
|
compressed_magic[1] = 'l';
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
//===- WriterInternals.h - Data structures shared by the Writer -*- C++ -*-===//
|
//===- WriterInternals.h - Data structures shared by the Writer -*- C++ -*-===//
|
||||||
//
|
//
|
||||||
// The LLVM Compiler Infrastructure
|
// The LLVM Compiler Infrastructure
|
||||||
//
|
//
|
||||||
// This file was developed by the LLVM research group and is distributed under
|
// This file was developed by the LLVM research group and is distributed under
|
||||||
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
// the University of Illinois Open Source License. See LICENSE.TXT for details.
|
||||||
//
|
//
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
//
|
//
|
||||||
// This header defines the interface used between components of the bytecode
|
// This header defines the interface used between components of the bytecode
|
||||||
@ -47,24 +47,24 @@ private:
|
|||||||
void outputInstructions(const Function *F);
|
void outputInstructions(const Function *F);
|
||||||
void outputInstruction(const Instruction &I);
|
void outputInstruction(const Instruction &I);
|
||||||
void outputInstructionFormat0(const Instruction *I, unsigned Opcode,
|
void outputInstructionFormat0(const Instruction *I, unsigned Opcode,
|
||||||
const SlotCalculator &Table,
|
const SlotCalculator &Table,
|
||||||
unsigned Type);
|
unsigned Type);
|
||||||
void outputInstrVarArgsCall(const Instruction *I,
|
void outputInstrVarArgsCall(const Instruction *I,
|
||||||
unsigned Opcode,
|
unsigned Opcode,
|
||||||
const SlotCalculator &Table,
|
const SlotCalculator &Table,
|
||||||
unsigned Type) ;
|
unsigned Type) ;
|
||||||
inline void outputInstructionFormat1(const Instruction *I,
|
inline void outputInstructionFormat1(const Instruction *I,
|
||||||
unsigned Opcode,
|
unsigned Opcode,
|
||||||
unsigned *Slots,
|
unsigned *Slots,
|
||||||
unsigned Type) ;
|
unsigned Type) ;
|
||||||
inline void outputInstructionFormat2(const Instruction *I,
|
inline void outputInstructionFormat2(const Instruction *I,
|
||||||
unsigned Opcode,
|
unsigned Opcode,
|
||||||
unsigned *Slots,
|
unsigned *Slots,
|
||||||
unsigned Type) ;
|
unsigned Type) ;
|
||||||
inline void outputInstructionFormat3(const Instruction *I,
|
inline void outputInstructionFormat3(const Instruction *I,
|
||||||
unsigned Opcode,
|
unsigned Opcode,
|
||||||
unsigned *Slots,
|
unsigned *Slots,
|
||||||
unsigned Type) ;
|
unsigned Type) ;
|
||||||
|
|
||||||
void outputModuleInfoBlock(const Module *C);
|
void outputModuleInfoBlock(const Module *C);
|
||||||
void outputSymbolTable(const SymbolTable &ST);
|
void outputSymbolTable(const SymbolTable &ST);
|
||||||
|
Reference in New Issue
Block a user