mirror of
https://github.com/ldc-developers/ldc.git
synced 2025-05-05 01:20:51 +03:00

Add the commandline options -fprofile-instr-generate[=filename] and -profile-instr-use=filename -fprofile-instr-generate -- Add instrumentation on branches, switches, and function entry; uses LLVM's InstrProf pass. -- Link to profile runtime that writes instrumentation counters to a file. -fprofile-instr-use -- Read profile data from a file and apply branch weights to branches and switches, and annotate functions with entrycount in LLVM IR. -- Functions with low or high entrycount are marked with 'cold' or 'inlinehint'. The only statement type without PGO yet is "try-finally". A new pragma, `pragma(LDC_profile_instr, [ true | false ])`, is added to selectively disable/enable instrumentation of functions (granularity = whole functions). The runtime library ldc-profile-rt is a copy of LLVM compiler-rt lib/profile. It has to be exactly in-sync with the LLVM version, and thus we need a copy for each PGO-supported LLVM (>=3.7). import ldc.profile for a D interface to ldc-profile-rt (for example to reset execution counts after a program startup phase). The instrumentation data is mainly passed on to LLVM: function-entry counts and branch counts/probabilities. LDC marks functions as hot when "execution count is 30% of the maximum function execution count", and marks functions as cold if their count is 1% of maximum function execution count. The source of LLVM's llvm-profdata tool is hereby included in LDCs repository (different source for each LLVM version), and the binary is included in the install bin folder. The executable is named "ldc-profdata" to avoid clashing with llvm-profdata on the same machine. This is needed because profdata executable has to be in-sync with the LLVM version used to build LDC. Maintenance burden: for trunk LLVM, we have to keep ldc-profile-rt and llvm-profdata in sync. There is no diff with upstream; but because of active development there are the occasional API changes.
162 lines
5.8 KiB
C++
162 lines
5.8 KiB
C++
|
|
/* Compiler implementation of the D programming language
|
|
* Copyright (c) 1999-2014 by Digital Mars
|
|
* All Rights Reserved
|
|
* written by Walter Bright
|
|
* http://www.digitalmars.com
|
|
* Distributed under the Boost Software License, Version 1.0.
|
|
* http://www.boost.org/LICENSE_1_0.txt
|
|
* https://github.com/D-Programming-Language/dmd/blob/master/src/scope.h
|
|
*/
|
|
|
|
#ifndef DMD_SCOPE_H
|
|
#define DMD_SCOPE_H
|
|
|
|
#ifdef __DMC__
|
|
#pragma once
|
|
#endif
|
|
|
|
class Dsymbol;
|
|
class ScopeDsymbol;
|
|
class Identifier;
|
|
class Module;
|
|
class Statement;
|
|
class SwitchStatement;
|
|
class TryFinallyStatement;
|
|
class LabelStatement;
|
|
class ForeachStatement;
|
|
class ClassDeclaration;
|
|
class AggregateDeclaration;
|
|
class FuncDeclaration;
|
|
class UserAttributeDeclaration;
|
|
struct DocComment;
|
|
struct AA;
|
|
class TemplateInstance;
|
|
|
|
#include "dsymbol.h"
|
|
|
|
#if __GNUC__
|
|
// Requires a full definition for LINK
|
|
#include "mars.h"
|
|
#else
|
|
enum LINK;
|
|
enum PINLINE;
|
|
#endif
|
|
|
|
#define CSXthis_ctor 1 // called this()
|
|
#define CSXsuper_ctor 2 // called super()
|
|
#define CSXthis 4 // referenced this
|
|
#define CSXsuper 8 // referenced super
|
|
#define CSXlabel 0x10 // seen a label
|
|
#define CSXreturn 0x20 // seen a return statement
|
|
#define CSXany_ctor 0x40 // either this() or super() was called
|
|
#define CSXhalt 0x80 // assert(0)
|
|
|
|
// Flags that would not be inherited beyond scope nesting
|
|
#define SCOPEctor 0x0001 // constructor type
|
|
#define SCOPEnoaccesscheck 0x0002 // don't do access checks
|
|
#define SCOPEcondition 0x0004 // inside static if/assert condition
|
|
#define SCOPEdebug 0x0008 // inside debug conditional
|
|
|
|
// Flags that would be inherited beyond scope nesting
|
|
#define SCOPEconstraint 0x0010 // inside template constraint
|
|
#define SCOPEinvariant 0x0020 // inside invariant code
|
|
#define SCOPErequire 0x0040 // inside in contract code
|
|
#define SCOPEensure 0x0060 // inside out contract code
|
|
#define SCOPEcontract 0x0060 // [mask] we're inside contract code
|
|
#define SCOPEctfe 0x0080 // inside a ctfe-only expression
|
|
#define SCOPEcompile 0x0100 // inside __traits(compile)
|
|
|
|
#define SCOPEfree 0x8000 // is on free list
|
|
|
|
struct Scope
|
|
{
|
|
Scope *enclosing; // enclosing Scope
|
|
|
|
Module *module; // Root module
|
|
ScopeDsymbol *scopesym; // current symbol
|
|
ScopeDsymbol *sds; // if in static if, and declaring new symbols,
|
|
// sds gets the addMember()
|
|
FuncDeclaration *func; // function we are in
|
|
Dsymbol *parent; // parent to use
|
|
LabelStatement *slabel; // enclosing labelled statement
|
|
SwitchStatement *sw; // enclosing switch statement
|
|
TryFinallyStatement *tf; // enclosing try finally statement
|
|
OnScopeStatement *os; // enclosing scope(xxx) statement
|
|
Statement *sbreak; // enclosing statement that supports "break"
|
|
Statement *scontinue; // enclosing statement that supports "continue"
|
|
ForeachStatement *fes; // if nested function for ForeachStatement, this is it
|
|
Scope *callsc; // used for __FUNCTION__, __PRETTY_FUNCTION__ and __MODULE__
|
|
int inunion; // we're processing members of a union
|
|
int nofree; // set if shouldn't free it
|
|
int noctor; // set if constructor calls aren't allowed
|
|
int intypeof; // in typeof(exp)
|
|
VarDeclaration *lastVar; // Previous symbol used to prevent goto-skips-init
|
|
|
|
/* If minst && !tinst, it's in definitely non-speculative scope (eg. module member scope).
|
|
* If !minst && !tinst, it's in definitely speculative scope (eg. template constraint).
|
|
* If minst && tinst, it's in instantiated code scope without speculation.
|
|
* If !minst && tinst, it's in instantiated code scope with speculation.
|
|
*/
|
|
Module *minst; // root module where the instantiated templates should belong to
|
|
TemplateInstance *tinst; // enclosing template instance
|
|
|
|
unsigned callSuper; // primitive flow analysis for constructors
|
|
unsigned *fieldinit;
|
|
size_t fieldinit_dim;
|
|
|
|
structalign_t structalign; // alignment for struct members
|
|
LINK linkage; // linkage for external functions
|
|
PINLINE inlining; // inlining strategy for functions
|
|
|
|
Prot protection; // protection for class members
|
|
int explicitProtection; // set if in an explicit protection attribute
|
|
|
|
StorageClass stc; // storage class
|
|
char *depmsg; // customized deprecation message
|
|
|
|
unsigned flags;
|
|
|
|
UserAttributeDeclaration *userAttribDecl; // user defined attributes
|
|
|
|
#if IN_LLVM
|
|
bool emitInstrumentation; // whether to emit instrumentation with -fprofile-instr-generate
|
|
#endif
|
|
|
|
DocComment *lastdc; // documentation comment for last symbol at this scope
|
|
AA *anchorCounts; // lookup duplicate anchor name count
|
|
Identifier *prevAnchor; // qualified symbol name of last doc anchor
|
|
|
|
static Scope *freelist;
|
|
static Scope *alloc();
|
|
static Scope *createGlobal(Module *module);
|
|
|
|
Scope();
|
|
|
|
Scope *copy();
|
|
|
|
Scope *push();
|
|
Scope *push(ScopeDsymbol *ss);
|
|
Scope *pop();
|
|
|
|
Scope *startCTFE();
|
|
Scope *endCTFE();
|
|
|
|
void mergeCallSuper(Loc loc, unsigned cs);
|
|
|
|
unsigned *saveFieldInit();
|
|
void mergeFieldInit(Loc loc, unsigned *cses);
|
|
|
|
Module *instantiatingModule();
|
|
|
|
Dsymbol *search(Loc loc, Identifier *ident, Dsymbol **pscopesym, int flags = IgnoreNone);
|
|
static void deprecation10378(Loc loc, Dsymbol *sold, Dsymbol *snew);
|
|
Dsymbol *search_correct(Identifier *ident);
|
|
Dsymbol *insert(Dsymbol *s);
|
|
|
|
ClassDeclaration *getClassScope();
|
|
AggregateDeclaration *getStructClassScope();
|
|
void setNoFree();
|
|
};
|
|
|
|
#endif /* DMD_SCOPE_H */
|