llvm-6502/include/llvm/Linker/Linker.h
Rafael Espindola 55d5ea3be3 Split the set of identified struct types into opaque and non-opaque ones.
The non-opaque part can be structurally uniqued. To keep this to just
a hash lookup, we don't try to unique cyclic types.

Also change the type mapping algorithm to be optimistic about a type
not being recursive and only create a new type when proven to be wrong.
This is not as strong as trying to speculate that we can keep the source
type, but is simpler (no speculation to revert) and more powerfull
than what we had before (we don't copy non-recursive types at least).

I initially wrote this to try to replace the name based type merging.
It is not strong enough to replace it, but is is a useful addition.

With this patch the number of named struct types is a clang lto bootstrap goes
from 49674 to 15986.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@223278 91177308-0d34-0410-b5e6-96231b3b80d8
2014-12-03 22:36:37 +00:00

95 lines
2.8 KiB
C++

//===- Linker.h - Module Linker Interface -----------------------*- C++ -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_LINKER_LINKER_H
#define LLVM_LINKER_LINKER_H
#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/DenseMap.h"
#include "llvm/ADT/DenseSet.h"
#include <functional>
namespace llvm {
class DiagnosticInfo;
class Module;
class StructType;
class Type;
/// This class provides the core functionality of linking in LLVM. It keeps a
/// pointer to the merged module so far. It doesn't take ownership of the
/// module since it is assumed that the user of this class will want to do
/// something with it after the linking.
class Linker {
public:
typedef std::function<void(const DiagnosticInfo &)> DiagnosticHandlerFunction;
struct StructTypeKeyInfo {
struct KeyTy {
ArrayRef<Type *> ETypes;
bool IsPacked;
KeyTy(ArrayRef<Type *> E, bool P);
KeyTy(const StructType *ST);
bool operator==(const KeyTy &that) const;
bool operator!=(const KeyTy &that) const;
};
static StructType *getEmptyKey();
static StructType *getTombstoneKey();
static unsigned getHashValue(const KeyTy &Key);
static unsigned getHashValue(const StructType *ST);
static bool isEqual(const KeyTy &LHS, const StructType *RHS);
static bool isEqual(const StructType *LHS, const StructType *RHS);
};
typedef DenseMap<StructType *, bool, StructTypeKeyInfo>
NonOpaqueStructTypeSet;
typedef DenseSet<StructType *> OpaqueStructTypeSet;
struct IdentifiedStructTypeSet {
// The set of opaque types is the composite module.
OpaqueStructTypeSet OpaqueStructTypes;
// The set of identified but non opaque structures in the composite module.
NonOpaqueStructTypeSet NonOpaqueStructTypes;
void addNonOpaque(StructType *Ty);
void addOpaque(StructType *Ty);
StructType *findNonOpaque(ArrayRef<Type *> ETypes, bool IsPacked);
bool hasType(StructType *Ty);
};
Linker(Module *M, DiagnosticHandlerFunction DiagnosticHandler);
Linker(Module *M);
~Linker();
Module *getModule() const { return Composite; }
void deleteModule();
/// \brief Link \p Src into the composite. The source is destroyed.
/// Returns true on error.
bool linkInModule(Module *Src);
static bool LinkModules(Module *Dest, Module *Src,
DiagnosticHandlerFunction DiagnosticHandler);
static bool LinkModules(Module *Dest, Module *Src);
private:
void init(Module *M, DiagnosticHandlerFunction DiagnosticHandler);
Module *Composite;
IdentifiedStructTypeSet IdentifiedStructTypes;
DiagnosticHandlerFunction DiagnosticHandler;
};
} // End llvm namespace
#endif