view ir/irfunction.cpp @ 948:780530d1cad3

Revert templates to old behavior. While emitting a template instantiation only once is good for compile times and binary sizes, it doesn't work with linkonce linkage as inlined function bodies could be discarded. Since we don't want to inhibit inlining, templates are reverted to the previous behavior, where an instantiation is emitted for each module using it. In the future, a custom inlining pass may allow us to switch back to common/weak linkage and reenable smart template instance emission.
author Christian Kamm <kamm incasoftware de>
date Sun, 08 Feb 2009 21:44:46 +0100
parents 1714836f2c0b
children 9167d492cbc2
line wrap: on
line source


#include "gen/llvm.h"
#include "gen/tollvm.h"
#include "ir/irfunction.h"

#include <sstream>

//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////
//////////////////////////////////////////////////////////////////////////////

IrFunction::IrFunction(FuncDeclaration* fd)
{
    decl = fd;

    Type* t = fd->type->toBasetype();
    assert(t->ty == Tfunction);
    type = (TypeFunction*)t;
    func = NULL;
    allocapoint = NULL;

    queued = false;
    defined = false;

    retArg = NULL;
    thisArg = NULL;
    nestArg = NULL;

    nestedVar = NULL;
    
    _arguments = NULL;
    _argptr = NULL;
    
    nextUnique.push(0);
}

std::string IrFunction::getScopedLabelName(const char* ident)
{
    if(labelScopes.empty())
        return std::string(ident);

    std::string result = "__";
    for(unsigned int i = 0; i < labelScopes.size(); ++i)
        result += labelScopes[i] + "_";
    return result + ident;
}

void IrFunction::pushUniqueLabelScope(const char* name)
{
    std::ostringstream uniquename;
    uniquename << name << nextUnique.top()++;
    nextUnique.push(0);
    labelScopes.push_back(uniquename.str());
}

void IrFunction::popLabelScope()
{
    labelScopes.pop_back();
    nextUnique.pop();
}

void IrFunction::setNeverInline()
{
    assert(!func->hasFnAttr(llvm::Attribute::AlwaysInline) && "function can't be never- and always-inline at the same time");
    func->addFnAttr(llvm::Attribute::NoInline);
}

void IrFunction::setAlwaysInline()
{
    assert(!func->hasFnAttr(llvm::Attribute::NoInline) && "function can't be never- and always-inline at the same time");
    func->addFnAttr(llvm::Attribute::AlwaysInline);
}