There is no real need in FuncDeclaration::labmap

This commit is contained in:
Alexey Prokhin 2014-09-22 12:26:12 +04:00
parent e4a7cf87d0
commit a0b9f95869
9 changed files with 20 additions and 52 deletions

View file

@ -18,7 +18,6 @@
#if IN_LLVM #if IN_LLVM
#include <set> #include <set>
#include <map>
#include <string> #include <string>
#if LDC_LLVM_VER >= 305 #if LDC_LLVM_VER >= 305
#include "llvm/IR/DebugInfo.h" #include "llvm/IR/DebugInfo.h"
@ -777,11 +776,6 @@ public:
bool isIntrinsic(); bool isIntrinsic();
bool isVaIntrinsic(); bool isVaIntrinsic();
// we keep our own table of label statements as LabelDsymbolS
// don't always carry their corresponding statement along ...
typedef std::map<const char*, LabelStatement*> LabelMap;
LabelMap labmap;
// true if overridden with the pragma(LDC_allow_inline); stmt // true if overridden with the pragma(LDC_allow_inline); stmt
bool allowInlining; bool allowInlining;

View file

@ -5047,11 +5047,6 @@ Statement *LabelStatement::semantic(Scope *sc)
statement = statement->semantic(sc); statement = statement->semantic(sc);
sc->pop(); sc->pop();
#if IN_LLVM
// LDC put in labmap
fd->labmap[ident->toChars()] = this;
#endif
return this; return this;
} }

View file

@ -822,8 +822,8 @@ public:
void accept(Visitor *v) { v->visit(this); } void accept(Visitor *v) { v->visit(this); }
#if IN_LLVM #if IN_LLVM
// non-zero if this is a branch, contains the target labels identifier // non-zero if this is a branch, contains the target label
Identifier* isBranchToLabel; LabelDsymbol* isBranchToLabel;
#endif #endif
}; };

View file

@ -2888,7 +2888,7 @@ namespace AsmParserx8664
else if ( e->op == TOKdsymbol ) else if ( e->op == TOKdsymbol )
{ {
LabelDsymbol * lbl = ( LabelDsymbol * ) ( ( DsymbolExp * ) e )->s; LabelDsymbol * lbl = ( LabelDsymbol * ) ( ( DsymbolExp * ) e )->s;
stmt->isBranchToLabel = lbl->ident; stmt->isBranchToLabel = lbl;
use_star = false; use_star = false;
addLabel ( lbl->ident->toChars() ); addLabel ( lbl->ident->toChars() );

View file

@ -521,7 +521,7 @@ void AsmBlockStatement_toIR(AsmBlockStatement *stmt, IRState* p)
// a post-asm switch // a post-asm switch
// maps each goto destination to its special value // maps each goto destination to its special value
std::map<Identifier*, int> gotoToVal; std::map<LabelDsymbol*, int> gotoToVal;
// location of the special value determining the goto label // location of the special value determining the goto label
// will be set if post-asm dispatcher block is needed // will be set if post-asm dispatcher block is needed
@ -559,7 +559,7 @@ void AsmBlockStatement_toIR(AsmBlockStatement *stmt, IRState* p)
end = asmblock->internalLabels.end(); end = asmblock->internalLabels.end();
bool skip = false; bool skip = false;
for(it = asmblock->internalLabels.begin(); it != end; ++it) for(it = asmblock->internalLabels.begin(); it != end; ++it)
if((*it)->equals(a->isBranchToLabel)) if((*it)->equals(a->isBranchToLabel->ident))
skip = true; skip = true;
if(skip) if(skip)
continue; continue;
@ -572,8 +572,8 @@ void AsmBlockStatement_toIR(AsmBlockStatement *stmt, IRState* p)
gotoToVal[a->isBranchToLabel] = n_goto; gotoToVal[a->isBranchToLabel] = n_goto;
// provide an in-asm target for the branch and set value // provide an in-asm target for the branch and set value
IF_LOG Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->string); IF_LOG Logger::println("statement '%s' references outer label '%s': creating forwarder", a->code.c_str(), a->isBranchToLabel->ident->string);
printLabelName(code, fdmangle, a->isBranchToLabel->string); printLabelName(code, fdmangle, a->isBranchToLabel->ident->string);
code << ":\n\t"; code << ":\n\t";
code << "movl $<<in" << n_goto << ">>, $<<out0>>\n"; code << "movl $<<in" << n_goto << ">>, $<<out0>>\n";
//FIXME: Store the value -> label mapping somewhere, so it can be referenced later //FIXME: Store the value -> label mapping somewhere, so it can be referenced later
@ -754,7 +754,7 @@ void AsmBlockStatement_toIR(AsmBlockStatement *stmt, IRState* p)
llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, gotoToVal.size()); llvm::SwitchInst* sw = p->ir->CreateSwitch(val, bb, gotoToVal.size());
// add all cases // add all cases
std::map<Identifier*, int>::iterator it, end = gotoToVal.end(); std::map<LabelDsymbol*, int>::iterator it, end = gotoToVal.end();
for(it = gotoToVal.begin(); it != end; ++it) for(it = gotoToVal.begin(); it != end; ++it)
{ {
llvm::BasicBlock* casebb = llvm::BasicBlock::Create(gIR->context(), "case", p->topfunc(), bb); llvm::BasicBlock* casebb = llvm::BasicBlock::Create(gIR->context(), "case", p->topfunc(), bb);

View file

@ -92,7 +92,7 @@ struct IRAsmStmt
std::vector<LLValue*> in; std::vector<LLValue*> in;
// if this is nonzero, it contains the target label // if this is nonzero, it contains the target label
Identifier* isBranchToLabel; LabelDsymbol* isBranchToLabel;
}; };
struct IRAsmBlock struct IRAsmBlock

View file

@ -223,42 +223,23 @@ LLValue *DtoModuleFileName(Module* M, const Loc& loc)
} }
} }
/****************************************************************************************/
/*////////////////////////////////////////////////////////////////////////////////////////
// LABEL HELPER
////////////////////////////////////////////////////////////////////////////////////////*/
LabelStatement* DtoLabelStatement(Identifier* ident)
{
FuncDeclaration* fd = gIR->func()->decl;
FuncDeclaration::LabelMap::iterator iter = fd->labmap.find(ident->toChars());
if (iter == fd->labmap.end())
{
if (fd->returnLabel && fd->returnLabel->ident->equals(ident))
{
assert(fd->returnLabel->statement);
return fd->returnLabel->statement;
}
return NULL;
}
return iter->second;
}
/****************************************************************************************/ /****************************************************************************************/
/*//////////////////////////////////////////////////////////////////////////////////////// /*////////////////////////////////////////////////////////////////////////////////////////
// GOTO HELPER // GOTO HELPER
////////////////////////////////////////////////////////////////////////////////////////*/ ////////////////////////////////////////////////////////////////////////////////////////*/
void DtoGoto(Loc& loc, Identifier* target, TryFinallyStatement* sourceFinally) void DtoGoto(Loc &loc, LabelDsymbol *target, TryFinallyStatement *sourceFinally)
{ {
assert(!gIR->scopereturned()); assert(!gIR->scopereturned());
LabelStatement* lblstmt = DtoLabelStatement(target); LabelStatement *lblstmt = target->statement;
if(!lblstmt) { if (!lblstmt)
error(loc, "the label %s does not exist", target->toChars()); {
error(loc, "the label %s does not exist", target->ident->toChars());
fatal(); fatal();
} }
// find target basic block // find target basic block
std::string labelname = gIR->func()->gen->getScopedLabelName(target->toChars()); std::string labelname = gIR->func()->gen->getScopedLabelName(target->ident->toChars());
llvm::BasicBlock* &targetBB = gIR->func()->gen->labelToBB[labelname]; llvm::BasicBlock* &targetBB = gIR->func()->gen->labelToBB[labelname];
if (targetBB == NULL) if (targetBB == NULL)
targetBB = llvm::BasicBlock::Create(gIR->context(), "label_" + labelname, gIR->topfunc()); targetBB = llvm::BasicBlock::Create(gIR->context(), "label_" + labelname, gIR->topfunc());
@ -268,7 +249,8 @@ void DtoGoto(Loc& loc, Identifier* target, TryFinallyStatement* sourceFinally)
// goto into finally blocks is forbidden by the spec // goto into finally blocks is forbidden by the spec
// but should work fine // but should work fine
if(lblstmt->tf != sourceFinally) { if (lblstmt->tf != sourceFinally)
{
error(loc, "spec disallows goto into or out of finally block"); error(loc, "spec disallows goto into or out of finally block");
fatal(); fatal();
} }

View file

@ -50,12 +50,9 @@ void DtoAssert(Module* M, Loc& loc, DValue* msg);
// returns module file name // returns module file name
LLValue* DtoModuleFileName(Module* M, const Loc& loc); LLValue* DtoModuleFileName(Module* M, const Loc& loc);
// return the LabelStatement from the current function with the given identifier or NULL if not found
LabelStatement* DtoLabelStatement(Identifier* ident);
/// emits goto to LabelStatement with the target identifier /// emits goto to LabelStatement with the target identifier
/// the sourceFinally is only used for error checking /// the sourceFinally is only used for error checking
void DtoGoto(Loc& loc, Identifier* target, TryFinallyStatement* sourceFinally); void DtoGoto(Loc &loc, LabelDsymbol *target, TryFinallyStatement *sourceFinally);
// Generates IR for enclosing handlers between the current state and // Generates IR for enclosing handlers between the current state and
// the scope created by the 'target' statement. // the scope created by the 'target' statement.

View file

@ -1668,7 +1668,7 @@ public:
llvm::BasicBlock* oldend = gIR->scopeend(); llvm::BasicBlock* oldend = gIR->scopeend();
llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergoto", irs->topfunc(), oldend); llvm::BasicBlock* bb = llvm::BasicBlock::Create(gIR->context(), "aftergoto", irs->topfunc(), oldend);
DtoGoto(stmt->loc, stmt->label->ident, stmt->tf); DtoGoto(stmt->loc, stmt->label, stmt->tf);
irs->scope() = IRScope(bb, oldend); irs->scope() = IRScope(bb, oldend);
} }