2003-10-13 03:32:08 +00:00
|
|
|
//===-- SlotCalculator.cpp - Calculate what slots values land in ----------===//
|
2005-04-21 21:48:46 +00:00
|
|
|
//
|
2003-10-20 19:43:21 +00:00
|
|
|
// The LLVM Compiler Infrastructure
|
|
|
|
//
|
|
|
|
// 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.
|
2005-04-21 21:48:46 +00:00
|
|
|
//
|
2003-10-20 19:43:21 +00:00
|
|
|
//===----------------------------------------------------------------------===//
|
2001-06-06 20:29:01 +00:00
|
|
|
//
|
2004-01-20 00:57:32 +00:00
|
|
|
// This file implements a useful analysis step to figure out what numbered slots
|
|
|
|
// values in a program will land in (keeping track of per plane information).
|
2001-06-06 20:29:01 +00:00
|
|
|
//
|
2004-01-20 00:57:32 +00:00
|
|
|
// This is used when writing a file to disk, either in bytecode or assembly.
|
2001-06-06 20:29:01 +00:00
|
|
|
//
|
|
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
|
2004-07-04 11:42:49 +00:00
|
|
|
#include "SlotCalculator.h"
|
2004-01-14 23:34:39 +00:00
|
|
|
#include "llvm/Constants.h"
|
2001-06-06 20:29:01 +00:00
|
|
|
#include "llvm/DerivedTypes.h"
|
2004-07-04 11:42:49 +00:00
|
|
|
#include "llvm/Function.h"
|
2006-01-25 23:08:15 +00:00
|
|
|
#include "llvm/InlineAsm.h"
|
2004-07-29 12:17:34 +00:00
|
|
|
#include "llvm/Instructions.h"
|
2004-01-14 23:34:39 +00:00
|
|
|
#include "llvm/Module.h"
|
2007-01-06 07:24:44 +00:00
|
|
|
#include "llvm/TypeSymbolTable.h"
|
2004-07-04 11:42:49 +00:00
|
|
|
#include "llvm/Type.h"
|
2007-02-05 20:47:22 +00:00
|
|
|
#include "llvm/ValueSymbolTable.h"
|
2004-09-01 22:55:40 +00:00
|
|
|
#include "llvm/ADT/STLExtras.h"
|
2001-09-07 16:31:52 +00:00
|
|
|
#include <algorithm>
|
2004-07-04 11:42:49 +00:00
|
|
|
#include <functional>
|
2003-11-21 20:23:48 +00:00
|
|
|
using namespace llvm;
|
2003-11-11 22:41:34 +00:00
|
|
|
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
#ifndef NDEBUG
|
2006-11-29 00:19:40 +00:00
|
|
|
#include "llvm/Support/Streams.h"
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
#include "llvm/Support/CommandLine.h"
|
|
|
|
static cl::opt<bool> SlotCalculatorDebugOption("scdebug",cl::init(false),
|
|
|
|
cl::desc("Enable SlotCalculator debug output"), cl::Hidden);
|
|
|
|
#define SC_DEBUG(X) if (SlotCalculatorDebugOption) cerr << X
|
2001-09-07 16:31:52 +00:00
|
|
|
#else
|
|
|
|
#define SC_DEBUG(X)
|
|
|
|
#endif
|
2001-06-06 20:29:01 +00:00
|
|
|
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
void SlotCalculator::insertPrimitives() {
|
|
|
|
// Preload the table with the built-in types. These built-in types are
|
|
|
|
// inserted first to ensure that they have low integer indices which helps to
|
|
|
|
// keep bytecode sizes small. Note that the first group of indices must match
|
|
|
|
// the Type::TypeIDs for the primitive types. After that the integer types are
|
|
|
|
// added, but the order and value is not critical. What is critical is that
|
|
|
|
// the indices of these "well known" slot numbers be properly maintained in
|
|
|
|
// Reader.h which uses them directly to extract values of these types.
|
|
|
|
SC_DEBUG("Inserting primitive types:\n");
|
|
|
|
// See WellKnownTypeSlots in Reader.h
|
2007-02-10 04:51:21 +00:00
|
|
|
getOrCreateTypeSlot(Type::VoidTy ); // 0: VoidTySlot
|
|
|
|
getOrCreateTypeSlot(Type::FloatTy ); // 1: FloatTySlot
|
|
|
|
getOrCreateTypeSlot(Type::DoubleTy); // 2: DoubleTySlot
|
|
|
|
getOrCreateTypeSlot(Type::LabelTy ); // 3: LabelTySlot
|
2007-02-10 04:15:40 +00:00
|
|
|
assert(TypeMap.size() == Type::FirstDerivedTyID &&"Invalid primitive insert");
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
// Above here *must* correspond 1:1 with the primitive types.
|
2007-02-10 11:59:10 +00:00
|
|
|
getOrCreateTypeSlot(Type::Int1Ty ); // 4: Int1TySlot
|
2007-02-10 04:51:21 +00:00
|
|
|
getOrCreateTypeSlot(Type::Int8Ty ); // 5: Int8TySlot
|
|
|
|
getOrCreateTypeSlot(Type::Int16Ty ); // 6: Int16TySlot
|
|
|
|
getOrCreateTypeSlot(Type::Int32Ty ); // 7: Int32TySlot
|
|
|
|
getOrCreateTypeSlot(Type::Int64Ty ); // 8: Int64TySlot
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
}
|
|
|
|
|
2007-02-10 04:42:30 +00:00
|
|
|
SlotCalculator::SlotCalculator(const Module *M) {
|
2007-02-10 04:47:51 +00:00
|
|
|
assert(M);
|
2001-06-06 20:29:01 +00:00
|
|
|
TheModule = M;
|
|
|
|
|
For PR1064:
Implement the arbitrary bit-width integer feature. The feature allows
integers of any bitwidth (up to 64) to be defined instead of just 1, 8,
16, 32, and 64 bit integers.
This change does several things:
1. Introduces a new Derived Type, IntegerType, to represent the number of
bits in an integer. The Type classes SubclassData field is used to
store the number of bits. This allows 2^23 bits in an integer type.
2. Removes the five integer Type::TypeID values for the 1, 8, 16, 32 and
64-bit integers. These are replaced with just IntegerType which is not
a primitive any more.
3. Adjust the rest of LLVM to account for this change.
Note that while this incremental change lays the foundation for arbitrary
bit-width integers, LLVM has not yet been converted to actually deal with
them in any significant way. Most optimization passes, for example, will
still only deal with the byte-width integer types. Future increments
will rectify this situation.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33113 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-12 07:05:14 +00:00
|
|
|
insertPrimitives();
|
2001-09-07 16:31:52 +00:00
|
|
|
processModule();
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2002-04-07 20:49:59 +00:00
|
|
|
// processModule - Process all of the module level function declarations and
|
2001-09-07 16:31:52 +00:00
|
|
|
// types that are available.
|
|
|
|
//
|
|
|
|
void SlotCalculator::processModule() {
|
|
|
|
SC_DEBUG("begin processModule!\n");
|
2001-09-10 07:58:01 +00:00
|
|
|
|
2003-03-19 20:57:22 +00:00
|
|
|
// Add all of the global variables to the value table...
|
2001-10-13 06:35:09 +00:00
|
|
|
//
|
2005-05-05 22:21:19 +00:00
|
|
|
for (Module::const_global_iterator I = TheModule->global_begin(),
|
|
|
|
E = TheModule->global_end(); I != E; ++I)
|
2007-02-10 04:54:01 +00:00
|
|
|
CreateSlotIfNeeded(I);
|
2001-09-10 07:58:01 +00:00
|
|
|
|
2002-04-07 20:49:59 +00:00
|
|
|
// Scavenge the types out of the functions, then add the functions themselves
|
|
|
|
// to the value table...
|
2001-09-07 16:31:52 +00:00
|
|
|
//
|
2003-03-19 20:57:22 +00:00
|
|
|
for (Module::const_iterator I = TheModule->begin(), E = TheModule->end();
|
|
|
|
I != E; ++I)
|
2007-02-10 04:54:01 +00:00
|
|
|
CreateSlotIfNeeded(I);
|
2001-09-07 16:31:52 +00:00
|
|
|
|
2003-03-19 20:57:22 +00:00
|
|
|
// Add all of the module level constants used as initializers
|
|
|
|
//
|
2005-05-05 22:21:19 +00:00
|
|
|
for (Module::const_global_iterator I = TheModule->global_begin(),
|
|
|
|
E = TheModule->global_end(); I != E; ++I)
|
2003-03-19 20:57:22 +00:00
|
|
|
if (I->hasInitializer())
|
2007-02-10 04:54:01 +00:00
|
|
|
CreateSlotIfNeeded(I->getInitializer());
|
2003-03-19 20:57:22 +00:00
|
|
|
|
2004-01-14 23:34:39 +00:00
|
|
|
// Now that all global constants have been added, rearrange constant planes
|
|
|
|
// that contain constant strings so that the strings occur at the start of the
|
|
|
|
// plane, not somewhere in the middle.
|
|
|
|
//
|
2004-05-26 07:37:11 +00:00
|
|
|
for (unsigned plane = 0, e = Table.size(); plane != e; ++plane) {
|
|
|
|
if (const ArrayType *AT = dyn_cast<ArrayType>(Types[plane]))
|
2006-12-31 05:44:24 +00:00
|
|
|
if (AT->getElementType() == Type::Int8Ty) {
|
2004-07-04 11:42:49 +00:00
|
|
|
TypePlane &Plane = Table[plane];
|
|
|
|
unsigned FirstNonStringID = 0;
|
|
|
|
for (unsigned i = 0, e = Plane.size(); i != e; ++i)
|
2005-04-21 21:48:46 +00:00
|
|
|
if (isa<ConstantAggregateZero>(Plane[i]) ||
|
2005-04-22 04:01:18 +00:00
|
|
|
(isa<ConstantArray>(Plane[i]) &&
|
2004-10-24 04:27:59 +00:00
|
|
|
cast<ConstantArray>(Plane[i])->isString())) {
|
2004-07-04 11:42:49 +00:00
|
|
|
// Check to see if we have to shuffle this string around. If not,
|
|
|
|
// don't do anything.
|
|
|
|
if (i != FirstNonStringID) {
|
|
|
|
// Swap the plane entries....
|
|
|
|
std::swap(Plane[i], Plane[FirstNonStringID]);
|
2005-04-21 21:48:46 +00:00
|
|
|
|
2004-07-04 11:42:49 +00:00
|
|
|
// Keep the NodeMap up to date.
|
|
|
|
NodeMap[Plane[i]] = i;
|
|
|
|
NodeMap[Plane[FirstNonStringID]] = FirstNonStringID;
|
|
|
|
}
|
|
|
|
++FirstNonStringID;
|
|
|
|
}
|
2004-05-26 07:37:11 +00:00
|
|
|
}
|
2004-01-14 23:34:39 +00:00
|
|
|
}
|
2005-04-21 21:48:46 +00:00
|
|
|
|
|
|
|
// Scan all of the functions for their constants, which allows us to emit
|
2007-02-10 04:36:10 +00:00
|
|
|
// more compact modules.
|
2004-05-26 07:37:11 +00:00
|
|
|
SC_DEBUG("Inserting function constants:\n");
|
|
|
|
for (Module::const_iterator F = TheModule->begin(), E = TheModule->end();
|
|
|
|
F != E; ++F) {
|
2007-02-10 04:36:10 +00:00
|
|
|
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB)
|
|
|
|
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); 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))
|
2007-02-10 04:54:01 +00:00
|
|
|
CreateSlotIfNeeded(*OI);
|
2007-02-10 04:36:10 +00:00
|
|
|
}
|
|
|
|
getOrCreateTypeSlot(I->getType());
|
2006-01-25 23:08:15 +00:00
|
|
|
}
|
2004-01-10 23:46:13 +00:00
|
|
|
}
|
|
|
|
|
2001-09-10 07:58:01 +00:00
|
|
|
// Insert constants that are named at module level into the slot pool so that
|
|
|
|
// the module symbol table can refer to them...
|
2004-05-26 07:37:11 +00:00
|
|
|
SC_DEBUG("Inserting SymbolTable values:\n");
|
2007-01-06 07:24:44 +00:00
|
|
|
processTypeSymbolTable(&TheModule->getTypeSymbolTable());
|
|
|
|
processValueSymbolTable(&TheModule->getValueSymbolTable());
|
2001-09-07 16:31:52 +00:00
|
|
|
|
2004-01-10 23:46:13 +00:00
|
|
|
// Now that we have collected together all of the information relevant to the
|
|
|
|
// module, compactify the type table if it is particularly big and outputting
|
|
|
|
// a bytecode file. The basic problem we run into is that some programs have
|
|
|
|
// a large number of types, which causes the type field to overflow its size,
|
|
|
|
// which causes instructions to explode in size (particularly call
|
|
|
|
// instructions). To avoid this behavior, we "sort" the type table so that
|
|
|
|
// all non-value types are pushed to the end of the type table, giving nice
|
|
|
|
// low numbers to the types that can be used by instructions, thus reducing
|
|
|
|
// the amount of explodage we suffer.
|
2004-07-04 11:42:49 +00:00
|
|
|
if (Types.size() >= 64) {
|
2004-01-10 23:46:13 +00:00
|
|
|
unsigned FirstNonValueTypeID = 0;
|
2004-07-04 11:42:49 +00:00
|
|
|
for (unsigned i = 0, e = Types.size(); i != e; ++i)
|
|
|
|
if (Types[i]->isFirstClassType() || Types[i]->isPrimitiveType()) {
|
2004-01-10 23:46:13 +00:00
|
|
|
// Check to see if we have to shuffle this type around. If not, don't
|
|
|
|
// do anything.
|
|
|
|
if (i != FirstNonValueTypeID) {
|
|
|
|
// Swap the type ID's.
|
2004-07-04 11:42:49 +00:00
|
|
|
std::swap(Types[i], Types[FirstNonValueTypeID]);
|
2004-01-10 23:46:13 +00:00
|
|
|
|
2004-07-04 11:42:49 +00:00
|
|
|
// Keep the TypeMap up to date.
|
|
|
|
TypeMap[Types[i]] = i;
|
|
|
|
TypeMap[Types[FirstNonValueTypeID]] = FirstNonValueTypeID;
|
2004-01-10 23:46:13 +00:00
|
|
|
|
|
|
|
// When we move a type, make sure to move its value plane as needed.
|
2004-01-11 23:29:26 +00:00
|
|
|
if (Table.size() > FirstNonValueTypeID) {
|
|
|
|
if (Table.size() <= i) Table.resize(i+1);
|
|
|
|
std::swap(Table[i], Table[FirstNonValueTypeID]);
|
|
|
|
}
|
2004-01-10 23:46:13 +00:00
|
|
|
}
|
|
|
|
++FirstNonValueTypeID;
|
|
|
|
}
|
|
|
|
}
|
2007-02-10 05:54:33 +00:00
|
|
|
|
2007-02-10 06:38:19 +00:00
|
|
|
NumModuleTypes = getNumPlanes();
|
|
|
|
|
2001-09-07 16:31:52 +00:00
|
|
|
SC_DEBUG("end processModule!\n");
|
|
|
|
}
|
|
|
|
|
2007-01-06 07:24:44 +00:00
|
|
|
// processTypeSymbolTable - Insert all of the type sin the specified symbol
|
|
|
|
// table.
|
2007-02-05 20:47:22 +00:00
|
|
|
void SlotCalculator::processTypeSymbolTable(const TypeSymbolTable *TST) {
|
|
|
|
for (TypeSymbolTable::const_iterator TI = TST->begin(), TE = TST->end();
|
2007-01-06 07:24:44 +00:00
|
|
|
TI != TE; ++TI )
|
2007-02-10 04:15:40 +00:00
|
|
|
getOrCreateTypeSlot(TI->second);
|
2007-01-06 07:24:44 +00:00
|
|
|
}
|
|
|
|
|
2001-09-07 16:31:52 +00:00
|
|
|
// processSymbolTable - Insert all of the values in the specified symbol table
|
|
|
|
// into the values table...
|
|
|
|
//
|
2007-02-05 20:47:22 +00:00
|
|
|
void SlotCalculator::processValueSymbolTable(const ValueSymbolTable *VST) {
|
|
|
|
for (ValueSymbolTable::const_iterator VI = VST->begin(), VE = VST->end();
|
|
|
|
VI != VE; ++VI)
|
2007-02-12 05:18:08 +00:00
|
|
|
CreateSlotIfNeeded(VI->getValue());
|
2001-09-07 16:31:52 +00:00
|
|
|
}
|
2001-06-06 20:29:01 +00:00
|
|
|
|
2007-02-10 05:45:09 +00:00
|
|
|
void SlotCalculator::CreateSlotIfNeeded(const Value *V) {
|
|
|
|
// Check to see if it's already in!
|
|
|
|
if (NodeMap.count(V)) return;
|
|
|
|
|
|
|
|
const Type *Ty = V->getType();
|
|
|
|
assert(Ty != Type::VoidTy && "Can't insert void values!");
|
|
|
|
|
|
|
|
if (const Constant *C = dyn_cast<Constant>(V)) {
|
|
|
|
if (isa<GlobalValue>(C)) {
|
|
|
|
// Initializers for globals are handled explicitly elsewhere.
|
|
|
|
} else if (isa<ConstantArray>(C) && cast<ConstantArray>(C)->isString()) {
|
|
|
|
// Do not index the characters that make up constant strings. We emit
|
|
|
|
// constant strings as special entities that don't require their
|
|
|
|
// individual characters to be emitted.
|
|
|
|
if (!C->isNullValue())
|
|
|
|
ConstantStrings.push_back(cast<ConstantArray>(C));
|
|
|
|
} else {
|
|
|
|
// This makes sure that if a constant has uses (for example an array of
|
|
|
|
// const ints), that they are inserted also.
|
|
|
|
for (User::const_op_iterator I = C->op_begin(), E = C->op_end();
|
|
|
|
I != E; ++I)
|
|
|
|
CreateSlotIfNeeded(*I);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
unsigned TyPlane = getOrCreateTypeSlot(Ty);
|
|
|
|
if (Table.size() <= TyPlane) // Make sure we have the type plane allocated.
|
|
|
|
Table.resize(TyPlane+1, TypePlane());
|
|
|
|
|
|
|
|
// If this is the first value to get inserted into the type plane, make sure
|
|
|
|
// to insert the implicit null value.
|
|
|
|
if (Table[TyPlane].empty()) {
|
|
|
|
// Label's and opaque types can't have a null value.
|
|
|
|
if (Ty != Type::LabelTy && !isa<OpaqueType>(Ty)) {
|
|
|
|
Value *ZeroInitializer = Constant::getNullValue(Ty);
|
|
|
|
|
|
|
|
// If we are pushing zeroinit, it will be handled below.
|
|
|
|
if (V != ZeroInitializer) {
|
|
|
|
Table[TyPlane].push_back(ZeroInitializer);
|
|
|
|
NodeMap[ZeroInitializer] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Insert node into table and NodeMap...
|
|
|
|
NodeMap[V] = Table[TyPlane].size();
|
|
|
|
Table[TyPlane].push_back(V);
|
|
|
|
|
|
|
|
SC_DEBUG(" Inserting value [" << TyPlane << "] = " << *V << " slot=" <<
|
|
|
|
NodeMap[V] << "\n");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
unsigned SlotCalculator::getOrCreateTypeSlot(const Type *Ty) {
|
2007-02-10 06:42:23 +00:00
|
|
|
TypeMapType::iterator TyIt = TypeMap.find(Ty);
|
2007-02-10 05:45:09 +00:00
|
|
|
if (TyIt != TypeMap.end()) return TyIt->second;
|
|
|
|
|
2007-02-11 00:03:39 +00:00
|
|
|
// Insert into TypeMap.
|
2007-02-10 05:45:09 +00:00
|
|
|
unsigned ResultSlot = TypeMap[Ty] = Types.size();
|
|
|
|
Types.push_back(Ty);
|
|
|
|
SC_DEBUG(" Inserting type [" << ResultSlot << "] = " << *Ty << "\n" );
|
|
|
|
|
2007-02-11 00:03:39 +00:00
|
|
|
// Loop over any contained types in the definition, ensuring they are also
|
|
|
|
// inserted.
|
|
|
|
for (Type::subtype_iterator I = Ty->subtype_begin(), E = Ty->subtype_end();
|
2007-02-10 05:45:09 +00:00
|
|
|
I != E; ++I)
|
|
|
|
getOrCreateTypeSlot(*I);
|
|
|
|
|
|
|
|
return ResultSlot;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2007-02-11 00:03:39 +00:00
|
|
|
|
2003-10-20 19:10:06 +00:00
|
|
|
void SlotCalculator::incorporateFunction(const Function *F) {
|
2002-04-07 20:49:59 +00:00
|
|
|
SC_DEBUG("begin processFunction!\n");
|
2007-02-10 05:45:09 +00:00
|
|
|
|
2002-04-07 20:49:59 +00:00
|
|
|
// Iterate over function arguments, adding them to the value table...
|
2007-02-10 04:15:40 +00:00
|
|
|
for(Function::const_arg_iterator I = F->arg_begin(), E = F->arg_end();
|
|
|
|
I != E; ++I)
|
2007-02-10 05:45:09 +00:00
|
|
|
CreateFunctionValueSlot(I);
|
|
|
|
|
2001-09-07 16:31:52 +00:00
|
|
|
SC_DEBUG("Inserting Instructions:\n");
|
2007-02-10 05:45:09 +00:00
|
|
|
|
2001-09-07 16:31:52 +00:00
|
|
|
// Add all of the instructions to the type planes...
|
2004-01-15 20:24:09 +00:00
|
|
|
for (Function::const_iterator BB = F->begin(), E = F->end(); BB != E; ++BB) {
|
2007-02-10 05:45:09 +00:00
|
|
|
CreateFunctionValueSlot(BB);
|
2003-10-21 17:39:59 +00:00
|
|
|
for (BasicBlock::const_iterator I = BB->begin(), E = BB->end(); I!=E; ++I) {
|
2007-02-10 04:31:52 +00:00
|
|
|
if (I->getType() != Type::VoidTy)
|
2007-02-10 05:45:09 +00:00
|
|
|
CreateFunctionValueSlot(I);
|
2003-10-21 17:39:59 +00:00
|
|
|
}
|
2001-09-07 16:31:52 +00:00
|
|
|
}
|
2007-02-10 05:45:09 +00:00
|
|
|
|
2002-04-07 20:49:59 +00:00
|
|
|
SC_DEBUG("end processFunction!\n");
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
|
|
|
|
2002-04-07 22:49:37 +00:00
|
|
|
void SlotCalculator::purgeFunction() {
|
2002-04-07 20:49:59 +00:00
|
|
|
SC_DEBUG("begin purgeFunction!\n");
|
2007-02-10 05:45:09 +00:00
|
|
|
|
2004-01-18 21:07:07 +00:00
|
|
|
// Next, remove values from existing type planes
|
2007-02-10 06:38:19 +00:00
|
|
|
for (DenseMap<unsigned,unsigned,
|
|
|
|
ModuleLevelDenseMapKeyInfo>::iterator I = ModuleLevel.begin(),
|
|
|
|
E = ModuleLevel.end(); I != E; ++I) {
|
|
|
|
unsigned PlaneNo = I->first;
|
|
|
|
unsigned ModuleLev = I->second;
|
2007-02-10 05:45:09 +00:00
|
|
|
|
2007-02-10 06:09:41 +00:00
|
|
|
// Pop all function-local values in this type-plane off of Table.
|
2007-02-10 06:38:19 +00:00
|
|
|
TypePlane &Plane = getPlane(PlaneNo);
|
2007-02-10 06:09:41 +00:00
|
|
|
assert(ModuleLev < Plane.size() && "module levels higher than elements?");
|
|
|
|
for (unsigned i = ModuleLev, e = Plane.size(); i != e; ++i) {
|
2004-01-20 00:57:32 +00:00
|
|
|
NodeMap.erase(Plane.back()); // Erase from nodemap
|
|
|
|
Plane.pop_back(); // Shrink plane
|
2001-06-06 20:29:01 +00:00
|
|
|
}
|
2004-01-20 00:57:32 +00:00
|
|
|
}
|
2007-02-10 06:38:19 +00:00
|
|
|
|
|
|
|
ModuleLevel.clear();
|
|
|
|
|
2004-01-20 00:57:32 +00:00
|
|
|
// Finally, remove any type planes defined by the function...
|
Bye, Bye Compaction Tables. The benefit compaction tables provides doesn't
outweight its computational costs. This patch removes all compaction
table handling from the bcreader and bcwriter. For the record, here's the
difference betweeen having and not having compaction tables for some tests:
Test With Without Size Chg
Olden/mst 5,602 5,598 +0.1%
viterbi 18,026 17,795 +1.3%
obsequi 162,133 166,663 -2.8%
burg 224,090 228,148 -1.8%
kimwitu++ 4,933,263 5,121,159 -3.8%
176.gcc 8,470,424 9,141,539 -7.3%
It seems that it is more beneficial to larger files, but even on the largest
test case we have (176.gcc) it only amounts ot an I/O saving of 7.3%.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33661 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-30 19:36:46 +00:00
|
|
|
while (Table.size() > NumModuleTypes) {
|
|
|
|
TypePlane &Plane = Table.back();
|
|
|
|
SC_DEBUG("Removing Plane " << (Table.size()-1) << " of size "
|
|
|
|
<< Plane.size() << "\n");
|
2007-02-10 06:09:41 +00:00
|
|
|
for (unsigned i = 0, e = Plane.size(); i != e; ++i)
|
|
|
|
NodeMap.erase(Plane[i]); // Erase from nodemap
|
2007-02-10 05:45:09 +00:00
|
|
|
|
Bye, Bye Compaction Tables. The benefit compaction tables provides doesn't
outweight its computational costs. This patch removes all compaction
table handling from the bcreader and bcwriter. For the record, here's the
difference betweeen having and not having compaction tables for some tests:
Test With Without Size Chg
Olden/mst 5,602 5,598 +0.1%
viterbi 18,026 17,795 +1.3%
obsequi 162,133 166,663 -2.8%
burg 224,090 228,148 -1.8%
kimwitu++ 4,933,263 5,121,159 -3.8%
176.gcc 8,470,424 9,141,539 -7.3%
It seems that it is more beneficial to larger files, but even on the largest
test case we have (176.gcc) it only amounts ot an I/O saving of 7.3%.
git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33661 91177308-0d34-0410-b5e6-96231b3b80d8
2007-01-30 19:36:46 +00:00
|
|
|
Table.pop_back(); // Nuke the plane, we don't like it.
|
2004-01-18 21:07:07 +00:00
|
|
|
}
|
2007-02-10 05:45:09 +00:00
|
|
|
|
2004-01-18 21:07:07 +00:00
|
|
|
SC_DEBUG("end purgeFunction!\n");
|
|
|
|
}
|
|
|
|
|
2007-02-10 05:45:09 +00:00
|
|
|
void SlotCalculator::CreateFunctionValueSlot(const Value *V) {
|
|
|
|
assert(!NodeMap.count(V) && "Function-local value can't be inserted!");
|
|
|
|
|
2007-02-10 04:42:30 +00:00
|
|
|
const Type *Ty = V->getType();
|
|
|
|
assert(Ty != Type::VoidTy && "Can't insert void values!");
|
2007-02-10 05:45:09 +00:00
|
|
|
assert(!isa<Constant>(V) && "Not a function-local value!");
|
2007-02-10 04:42:30 +00:00
|
|
|
|
2007-02-10 04:47:51 +00:00
|
|
|
unsigned TyPlane = getOrCreateTypeSlot(Ty);
|
2007-02-10 04:29:03 +00:00
|
|
|
if (Table.size() <= TyPlane) // Make sure we have the type plane allocated.
|
|
|
|
Table.resize(TyPlane+1, TypePlane());
|
2007-02-10 04:22:30 +00:00
|
|
|
|
2007-02-10 06:09:41 +00:00
|
|
|
// If this is the first value noticed of this type within this function,
|
|
|
|
// remember the module level for this type plane in ModuleLevel. This reminds
|
|
|
|
// us to remove the values in purgeFunction and tells us how many to remove.
|
2007-02-10 06:38:19 +00:00
|
|
|
if (TyPlane < NumModuleTypes)
|
|
|
|
ModuleLevel.insert(std::make_pair(TyPlane, Table[TyPlane].size()));
|
2007-02-10 06:09:41 +00:00
|
|
|
|
2007-02-10 04:22:30 +00:00
|
|
|
// If this is the first value to get inserted into the type plane, make sure
|
2007-02-10 04:29:03 +00:00
|
|
|
// to insert the implicit null value.
|
|
|
|
if (Table[TyPlane].empty()) {
|
|
|
|
// Label's and opaque types can't have a null value.
|
|
|
|
if (Ty != Type::LabelTy && !isa<OpaqueType>(Ty)) {
|
|
|
|
Value *ZeroInitializer = Constant::getNullValue(Ty);
|
|
|
|
|
|
|
|
// If we are pushing zeroinit, it will be handled below.
|
|
|
|
if (V != ZeroInitializer) {
|
|
|
|
Table[TyPlane].push_back(ZeroInitializer);
|
|
|
|
NodeMap[ZeroInitializer] = 0;
|
|
|
|
}
|
2007-02-10 04:22:30 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Insert node into table and NodeMap...
|
2007-02-10 05:45:09 +00:00
|
|
|
NodeMap[V] = Table[TyPlane].size();
|
2007-02-10 04:29:03 +00:00
|
|
|
Table[TyPlane].push_back(V);
|
2007-02-10 04:22:30 +00:00
|
|
|
|
2007-02-10 04:29:03 +00:00
|
|
|
SC_DEBUG(" Inserting value [" << TyPlane << "] = " << *V << " slot=" <<
|
2007-02-10 05:45:09 +00:00
|
|
|
NodeMap[V] << "\n");
|
|
|
|
}
|
2007-02-10 04:15:40 +00:00
|
|
|
|