Land the long talked about "type system rewrite" patch. This

patch brings numerous advantages to LLVM.  One way to look at it
is through diffstat:
 109 files changed, 3005 insertions(+), 5906 deletions(-)

Removing almost 3K lines of code is a good thing.  Other advantages
include:

1. Value::getType() is a simple load that can be CSE'd, not a mutating
   union-find operation.
2. Types a uniqued and never move once created, defining away PATypeHolder.
3. Structs can be "named" now, and their name is part of the identity that
   uniques them.  This means that the compiler doesn't merge them structurally
   which makes the IR much less confusing.
4. Now that there is no way to get a cycle in a type graph without a named
   struct type, "upreferences" go away.
5. Type refinement is completely gone, which should make LTO much MUCH faster
   in some common cases with C++ code.
6. Types are now generally immutable, so we can use "Type *" instead 
   "const Type *" everywhere.

Downsides of this patch are that it removes some functions from the C API,
so people using those will have to upgrade to (not yet added) new API.  
"LLVM 3.0" is the right time to do this.

There are still some cleanups pending after this, this patch is large enough
as-is.




git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@134829 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Chris Lattner
2011-07-09 17:41:24 +00:00
parent c36ed70ec5
commit 1afcace3a3
109 changed files with 3158 additions and 6059 deletions

View File

@@ -15,7 +15,6 @@
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Module.h"
#include "llvm/DerivedTypes.h"
#include "llvm/TypeSymbolTable.h"
#include "llvm/Constant.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
using namespace llvm;
@@ -32,20 +31,13 @@ Module *llvm::CloneModule(const Module *M) {
return CloneModule(M, VMap);
}
Module *llvm::CloneModule(const Module *M,
ValueToValueMapTy &VMap) {
// First off, we need to create the new module...
Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) {
// First off, we need to create the new module.
Module *New = new Module(M->getModuleIdentifier(), M->getContext());
New->setDataLayout(M->getDataLayout());
New->setTargetTriple(M->getTargetTriple());
New->setModuleInlineAsm(M->getModuleInlineAsm());
// Copy all of the type symbol table entries over.
const TypeSymbolTable &TST = M->getTypeSymbolTable();
for (TypeSymbolTable::const_iterator TI = TST.begin(), TE = TST.end();
TI != TE; ++TI)
New->addTypeName(TI->first, TI->second);
// Copy all of the dependent libraries over.
for (Module::lib_iterator I = M->lib_begin(), E = M->lib_end(); I != E; ++I)
New->addLibrary(*I);
@@ -88,8 +80,7 @@ Module *llvm::CloneModule(const Module *M,
I != E; ++I) {
GlobalVariable *GV = cast<GlobalVariable>(VMap[I]);
if (I->hasInitializer())
GV->setInitializer(cast<Constant>(MapValue(I->getInitializer(),
VMap, RF_None)));
GV->setInitializer(MapValue(I->getInitializer(), VMap));
GV->setLinkage(I->getLinkage());
GV->setThreadLocal(I->isThreadLocal());
GV->setConstant(I->isConstant());
@@ -119,8 +110,8 @@ Module *llvm::CloneModule(const Module *M,
I != E; ++I) {
GlobalAlias *GA = cast<GlobalAlias>(VMap[I]);
GA->setLinkage(I->getLinkage());
if (const Constant* C = I->getAliasee())
GA->setAliasee(cast<Constant>(MapValue(C, VMap, RF_None)));
if (const Constant *C = I->getAliasee())
GA->setAliasee(MapValue(C, VMap));
}
// And named metadata....
@@ -129,8 +120,7 @@ Module *llvm::CloneModule(const Module *M,
const NamedMDNode &NMD = *I;
NamedMDNode *NewNMD = New->getOrInsertNamedMetadata(NMD.getName());
for (unsigned i = 0, e = NMD.getNumOperands(); i != e; ++i)
NewNMD->addOperand(cast<MDNode>(MapValue(NMD.getOperand(i), VMap,
RF_None)));
NewNMD->addOperand(MapValue(NMD.getOperand(i), VMap));
}
return New;

View File

@@ -66,7 +66,7 @@ namespace {
Constant *AbortFn;
// Used for expensive EH support.
const Type *JBLinkTy;
StructType *JBLinkTy;
GlobalVariable *JBListHead;
Constant *SetJmpFn, *LongJmpFn, *StackSaveFn, *StackRestoreFn;
bool useExpensiveEHSupport;
@@ -120,24 +120,16 @@ FunctionPass *llvm::createLowerInvokePass(const TargetLowering *TLI,
// doInitialization - Make sure that there is a prototype for abort in the
// current module.
bool LowerInvoke::doInitialization(Module &M) {
const Type *VoidPtrTy =
Type::getInt8PtrTy(M.getContext());
const Type *VoidPtrTy = Type::getInt8PtrTy(M.getContext());
if (useExpensiveEHSupport) {
// Insert a type for the linked list of jump buffers.
unsigned JBSize = TLI ? TLI->getJumpBufSize() : 0;
JBSize = JBSize ? JBSize : 200;
const Type *JmpBufTy = ArrayType::get(VoidPtrTy, JBSize);
Type *JmpBufTy = ArrayType::get(VoidPtrTy, JBSize);
{ // The type is recursive, so use a type holder.
std::vector<const Type*> Elements;
Elements.push_back(JmpBufTy);
OpaqueType *OT = OpaqueType::get(M.getContext());
Elements.push_back(PointerType::getUnqual(OT));
PATypeHolder JBLType(StructType::get(M.getContext(), Elements));
OT->refineAbstractTypeTo(JBLType.get()); // Complete the cycle.
JBLinkTy = JBLType.get();
M.addTypeName("llvm.sjljeh.jmpbufty", JBLinkTy);
}
JBLinkTy = StructType::createNamed(M.getContext(), "llvm.sjljeh.jmpbufty");
Type *Elts[] = { JmpBufTy, PointerType::getUnqual(JBLinkTy) };
JBLinkTy->setBody(Elts);
const Type *PtrJBList = PointerType::getUnqual(JBLinkTy);

View File

@@ -13,16 +13,17 @@
//===----------------------------------------------------------------------===//
#include "llvm/Transforms/Utils/ValueMapper.h"
#include "llvm/Type.h"
#include "llvm/Constants.h"
#include "llvm/Function.h"
#include "llvm/Instructions.h"
#include "llvm/Metadata.h"
#include "llvm/ADT/SmallVector.h"
using namespace llvm;
Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM,
RemapFlags Flags) {
// Out of line method to get vtable etc for class.
void ValueMapTypeRemapper::Anchor() {}
Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM, RemapFlags Flags,
ValueMapTypeRemapper *TypeMapper) {
ValueToValueMapTy::iterator I = VM.find(V);
// If the value already exists in the map, use it.
@@ -46,14 +47,14 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM,
// Check all operands to see if any need to be remapped.
for (unsigned i = 0, e = MD->getNumOperands(); i != e; ++i) {
Value *OP = MD->getOperand(i);
if (OP == 0 || MapValue(OP, VM, Flags) == OP) continue;
if (OP == 0 || MapValue(OP, VM, Flags, TypeMapper) == OP) continue;
// Ok, at least one operand needs remapping.
SmallVector<Value*, 4> Elts;
Elts.reserve(MD->getNumOperands());
for (i = 0; i != e; ++i) {
Value *Op = MD->getOperand(i);
Elts.push_back(Op ? MapValue(Op, VM, Flags) : 0);
Elts.push_back(Op ? MapValue(Op, VM, Flags, TypeMapper) : 0);
}
MDNode *NewMD = MDNode::get(V->getContext(), Elts);
Dummy->replaceAllUsesWith(NewMD);
@@ -76,51 +77,75 @@ Value *llvm::MapValue(const Value *V, ValueToValueMapTy &VM,
return 0;
if (BlockAddress *BA = dyn_cast<BlockAddress>(C)) {
Function *F = cast<Function>(MapValue(BA->getFunction(), VM, Flags));
Function *F =
cast<Function>(MapValue(BA->getFunction(), VM, Flags, TypeMapper));
BasicBlock *BB = cast_or_null<BasicBlock>(MapValue(BA->getBasicBlock(), VM,
Flags));
Flags, TypeMapper));
return VM[V] = BlockAddress::get(F, BB ? BB : BA->getBasicBlock());
}
for (unsigned i = 0, e = C->getNumOperands(); i != e; ++i) {
Value *Op = C->getOperand(i);
Value *Mapped = MapValue(Op, VM, Flags);
if (Mapped == C) continue;
// Okay, the operands don't all match. We've already processed some or all
// of the operands, set them up now.
std::vector<Constant*> Ops;
Ops.reserve(C->getNumOperands());
for (unsigned j = 0; j != i; ++j)
Ops.push_back(cast<Constant>(C->getOperand(i)));
Ops.push_back(cast<Constant>(Mapped));
// Map the rest of the operands that aren't processed yet.
for (++i; i != e; ++i)
Ops.push_back(cast<Constant>(MapValue(C->getOperand(i), VM, Flags)));
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
return VM[V] = CE->getWithOperands(Ops);
if (ConstantArray *CA = dyn_cast<ConstantArray>(C))
return VM[V] = ConstantArray::get(CA->getType(), Ops);
if (ConstantStruct *CS = dyn_cast<ConstantStruct>(C))
return VM[V] = ConstantStruct::get(CS->getType(), Ops);
assert(isa<ConstantVector>(C) && "Unknown mapped constant type");
return VM[V] = ConstantVector::get(Ops);
// Otherwise, we have some other constant to remap. Start by checking to see
// if all operands have an identity remapping.
unsigned OpNo = 0, NumOperands = C->getNumOperands();
Value *Mapped = 0;
for (; OpNo != NumOperands; ++OpNo) {
Value *Op = C->getOperand(OpNo);
Mapped = MapValue(Op, VM, Flags, TypeMapper);
if (Mapped != C) break;
}
// See if the type mapper wants to remap the type as well.
Type *NewTy = C->getType();
if (TypeMapper)
NewTy = TypeMapper->remapType(NewTy);
// If we reach here, all of the operands of the constant match.
return VM[V] = C;
// If the result type and all operands match up, then just insert an identity
// mapping.
if (OpNo == NumOperands && NewTy == C->getType())
return VM[V] = C;
// Okay, we need to create a new constant. We've already processed some or
// all of the operands, set them all up now.
SmallVector<Constant*, 8> Ops;
Ops.reserve(NumOperands);
for (unsigned j = 0; j != OpNo; ++j)
Ops.push_back(cast<Constant>(C->getOperand(j)));
// If one of the operands mismatch, push it and the other mapped operands.
if (OpNo != NumOperands) {
Ops.push_back(cast<Constant>(Mapped));
// Map the rest of the operands that aren't processed yet.
for (++OpNo; OpNo != NumOperands; ++OpNo)
Ops.push_back(MapValue(cast<Constant>(C->getOperand(OpNo)), VM,
Flags, TypeMapper));
}
if (ConstantExpr *CE = dyn_cast<ConstantExpr>(C))
return VM[V] = CE->getWithOperands(Ops, NewTy);
if (isa<ConstantArray>(C))
return VM[V] = ConstantArray::get(cast<ArrayType>(NewTy), Ops);
if (isa<ConstantStruct>(C))
return VM[V] = ConstantStruct::get(cast<StructType>(NewTy), Ops);
if (isa<ConstantVector>(C))
return VM[V] = ConstantVector::get(Ops);
// If this is a no-operand constant, it must be because the type was remapped.
if (isa<UndefValue>(C))
return VM[V] = UndefValue::get(NewTy);
if (isa<ConstantAggregateZero>(C))
return VM[V] = ConstantAggregateZero::get(NewTy);
assert(isa<ConstantPointerNull>(C));
return VM[V] = ConstantPointerNull::get(cast<PointerType>(NewTy));
}
/// RemapInstruction - Convert the instruction operands from referencing the
/// current values into those specified by VMap.
///
void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap,
RemapFlags Flags) {
RemapFlags Flags, ValueMapTypeRemapper *TypeMapper){
// Remap operands.
for (User::op_iterator op = I->op_begin(), E = I->op_end(); op != E; ++op) {
Value *V = MapValue(*op, VMap, Flags);
Value *V = MapValue(*op, VMap, Flags, TypeMapper);
// If we aren't ignoring missing entries, assert that something happened.
if (V != 0)
*op = V;
@@ -147,9 +172,13 @@ void llvm::RemapInstruction(Instruction *I, ValueToValueMapTy &VMap,
I->getAllMetadata(MDs);
for (SmallVectorImpl<std::pair<unsigned, MDNode *> >::iterator
MI = MDs.begin(), ME = MDs.end(); MI != ME; ++MI) {
Value *Old = MI->second;
Value *New = MapValue(Old, VMap, Flags);
MDNode *Old = MI->second;
MDNode *New = MapValue(Old, VMap, Flags, TypeMapper);
if (New != Old)
I->setMetadata(MI->first, cast<MDNode>(New));
I->setMetadata(MI->first, New);
}
// If the instruction's type is being remapped, do so now.
if (TypeMapper)
I->mutateType(TypeMapper->remapType(I->getType()));
}