Skip to content

Commit

Permalink
Memoize InlineAsms into the LLVMContext and delete them on shutdown.
Browse files Browse the repository at this point in the history
Fixes PR803.


git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@99143 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
jyasskin committed Mar 21, 2010
1 parent f65b0e9 commit bf48a9b
Show file tree
Hide file tree
Showing 4 changed files with 84 additions and 14 deletions.
19 changes: 16 additions & 3 deletions include/llvm/InlineAsm.h
Original file line number Diff line number Diff line change
Expand Up @@ -24,19 +24,32 @@ namespace llvm {
class PointerType;
class FunctionType;
class Module;
struct InlineAsmKeyType;
template<class ValType, class TypeClass, class ConstantClass, bool HasLargeKey>
class ConstantUniqueMap;
template<class ConstantClass, class TypeClass, class ValType>
struct ConstantCreator;

class InlineAsm : public Value {
friend struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType>;
friend class ConstantUniqueMap<InlineAsmKeyType, PointerType, InlineAsm,
false>;

InlineAsm(const InlineAsm &); // do not implement
void operator=(const InlineAsm&); // do not implement

std::string AsmString, Constraints;
bool HasSideEffects;
bool IsAlignStack;

InlineAsm(const FunctionType *Ty, StringRef AsmString,
StringRef Constraints, bool hasSideEffects,
bool isAlignStack = false);
InlineAsm(const PointerType *Ty, const std::string &AsmString,
const std::string &Constraints, bool hasSideEffects,
bool isAlignStack);
virtual ~InlineAsm();

/// When the ConstantUniqueMap merges two types and makes two InlineAsms
/// identical, it destroys one of them with this method.
void destroyConstant();
public:

/// InlineAsm::get - Return the specified uniqued inline asm string.
Expand Down
51 changes: 51 additions & 0 deletions lib/VMCore/ConstantsContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
#ifndef LLVM_CONSTANTSCONTEXT_H
#define LLVM_CONSTANTSCONTEXT_H

#include "llvm/InlineAsm.h"
#include "llvm/Instructions.h"
#include "llvm/Operator.h"
#include "llvm/Support/Debug.h"
Expand Down Expand Up @@ -327,6 +328,39 @@ struct ExprMapKeyType {
}
};

struct InlineAsmKeyType {
InlineAsmKeyType(StringRef AsmString,
StringRef Constraints, bool hasSideEffects,
bool isAlignStack)
: asm_string(AsmString), constraints(Constraints),
has_side_effects(hasSideEffects), is_align_stack(isAlignStack) {}
std::string asm_string;
std::string constraints;
bool has_side_effects;
bool is_align_stack;
bool operator==(const InlineAsmKeyType& that) const {
return this->asm_string == that.asm_string &&
this->constraints == that.constraints &&
this->has_side_effects == that.has_side_effects &&
this->is_align_stack == that.is_align_stack;
}
bool operator<(const InlineAsmKeyType& that) const {
if (this->asm_string != that.asm_string)
return this->asm_string < that.asm_string;
if (this->constraints != that.constraints)
return this->constraints < that.constraints;
if (this->has_side_effects != that.has_side_effects)
return this->has_side_effects < that.has_side_effects;
if (this->is_align_stack != that.is_align_stack)
return this->is_align_stack < that.is_align_stack;
return false;
}

bool operator!=(const InlineAsmKeyType& that) const {
return !(*this == that);
}
};

// The number of operands for each ConstantCreator::create method is
// determined by the ConstantTraits template.
// ConstantCreator - A class that is used to create constants by
Expand Down Expand Up @@ -517,6 +551,23 @@ struct ConstantKeyData<UndefValue> {
}
};

template<>
struct ConstantCreator<InlineAsm, PointerType, InlineAsmKeyType> {
static InlineAsm *create(const PointerType *Ty, const InlineAsmKeyType &Key) {
return new InlineAsm(Ty, Key.asm_string, Key.constraints,
Key.has_side_effects, Key.is_align_stack);
}
};

template<>
struct ConstantKeyData<InlineAsm> {
typedef InlineAsmKeyType ValType;
static ValType getValType(InlineAsm *Asm) {
return InlineAsmKeyType(Asm->getAsmString(), Asm->getConstraintString(),
Asm->hasSideEffects(), Asm->isAlignStack());
}
};

template<class ValType, class TypeClass, class ConstantClass,
bool HasLargeKey = false /*true for arrays and structs*/ >
class ConstantUniqueMap : public AbstractTypeUser {
Expand Down
25 changes: 14 additions & 11 deletions lib/VMCore/InlineAsm.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@
//===----------------------------------------------------------------------===//

#include "llvm/InlineAsm.h"
#include "ConstantsContext.h"
#include "LLVMContextImpl.h"
#include "llvm/DerivedTypes.h"
#include <algorithm>
#include <cctype>
Expand All @@ -23,28 +25,29 @@ InlineAsm::~InlineAsm() {
}


// NOTE: when memoizing the function type, we have to be careful to handle the
// case when the type gets refined.

InlineAsm *InlineAsm::get(const FunctionType *Ty, StringRef AsmString,
StringRef Constraints, bool hasSideEffects,
bool isAlignStack) {
// FIXME: memoize!
return new InlineAsm(Ty, AsmString, Constraints, hasSideEffects,
isAlignStack);
InlineAsmKeyType Key(AsmString, Constraints, hasSideEffects, isAlignStack);
LLVMContextImpl *pImpl = Ty->getContext().pImpl;
return pImpl->InlineAsms.getOrCreate(PointerType::getUnqual(Ty), Key);
}

InlineAsm::InlineAsm(const FunctionType *Ty, StringRef asmString,
StringRef constraints, bool hasSideEffects,
InlineAsm::InlineAsm(const PointerType *Ty, const std::string &asmString,
const std::string &constraints, bool hasSideEffects,
bool isAlignStack)
: Value(PointerType::getUnqual(Ty),
Value::InlineAsmVal),
: Value(Ty, Value::InlineAsmVal),
AsmString(asmString),
Constraints(constraints), HasSideEffects(hasSideEffects),
IsAlignStack(isAlignStack) {

// Do various checks on the constraint string and type.
assert(Verify(Ty, constraints) && "Function type not legal for constraints!");
assert(Verify(getFunctionType(), constraints) &&
"Function type not legal for constraints!");
}

void InlineAsm::destroyConstant() {
delete this;
}

const FunctionType *InlineAsm::getFunctionType() const {
Expand Down
3 changes: 3 additions & 0 deletions lib/VMCore/LLVMContextImpl.h
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ class LLVMContextImpl {

DenseMap<std::pair<Function*, BasicBlock*> , BlockAddress*> BlockAddresses;
ConstantUniqueMap<ExprMapKeyType, Type, ConstantExpr> ExprConstants;

ConstantUniqueMap<InlineAsmKeyType, PointerType, InlineAsm> InlineAsms;

ConstantInt *TheTrueVal;
ConstantInt *TheFalseVal;
Expand Down Expand Up @@ -224,6 +226,7 @@ class LLVMContextImpl {
AggZeroConstants.freeConstants();
NullPtrConstants.freeConstants();
UndefValueConstants.freeConstants();
InlineAsms.freeConstants();
for (IntMapTy::iterator I = IntConstants.begin(), E = IntConstants.end();
I != E; ++I) {
if (I->second->use_empty())
Expand Down

0 comments on commit bf48a9b

Please sign in to comment.