Commit daefbbb6 authored by Kevin Modzelewski's avatar Kevin Modzelewski

Run clang-format ("make format") on the codebase

Changed the indentation of pretty much the entire codebase.

It did some things that I don't like that seem not configurable,
but overall it seems like an improvement, and nice to have a
canonical format going forward.
parent c0c916c4
......@@ -22,21 +22,20 @@
namespace pyston {
template <typename T>
class BBAnalyzer {
public:
typedef std::unordered_map<std::string, T> Map;
typedef std::unordered_map<CFGBlock*, Map> AllMap;
template <typename T> class BBAnalyzer {
public:
typedef std::unordered_map<std::string, T> Map;
typedef std::unordered_map<CFGBlock*, Map> AllMap;
virtual ~BBAnalyzer() {}
virtual ~BBAnalyzer() {}
virtual T merge(T from, T into) const = 0;
virtual T mergeBlank(T into) const = 0;
virtual void processBB(Map &starting, CFGBlock *block) const = 0;
virtual T merge(T from, T into) const = 0;
virtual T mergeBlank(T into) const = 0;
virtual void processBB(Map& starting, CFGBlock* block) const = 0;
};
template <typename T>
typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &analyzer, bool reverse) {
typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T>& analyzer, bool reverse) {
assert(!reverse);
typedef typename BBAnalyzer<T>::Map Map;
......@@ -49,17 +48,18 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &
q.push_back(cfg->getStartingBlock());
while (q.size()) {
CFGBlock *block = q.back();
CFGBlock* block = q.back();
q.pop_back();
Map initial = states[block];
if (VERBOSITY("analysis") >= 2) printf("fpc on block %d - %ld entries\n", block->idx, initial.size());
if (VERBOSITY("analysis") >= 2)
printf("fpc on block %d - %ld entries\n", block->idx, initial.size());
Map ending = Map(initial);
analyzer.processBB(ending, block);
for (int i = 0; i < block->successors.size(); i++) {
CFGBlock *next_block = block->successors[i];
CFGBlock* next_block = block->successors[i];
bool changed = false;
bool initial = false;
if (states.count(next_block) == 0) {
......@@ -67,8 +67,8 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &
initial = true;
}
Map &next = states[next_block];
for (const auto &p : ending) {
Map& next = states[next_block];
for (const auto& p : ending) {
if (next.count(p.first) == 0) {
changed = true;
if (initial) {
......@@ -77,7 +77,7 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &
next[p.first] = analyzer.mergeBlank(p.second);
}
} else {
T &next_elt = next[p.first];
T& next_elt = next[p.first];
T new_elt = analyzer.merge(p.second, next_elt);
if (next_elt != new_elt) {
......@@ -87,7 +87,7 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &
}
}
for (const auto &p : ending) {
for (const auto& p : ending) {
if (ending.count(p.first))
continue;
......@@ -108,7 +108,6 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &
return states;
}
}
#endif
This diff is collapsed.
......@@ -27,52 +27,50 @@ class CFGBlock;
class ScopeInfo;
class LivenessAnalysis {
public:
bool isLiveAtEnd(const std::string &name, CFGBlock *block);
public:
bool isLiveAtEnd(const std::string& name, CFGBlock* block);
};
class DefinednessAnalysis {
public:
enum DefinitionLevel {
Undefined,
PotentiallyDefined,
Defined,
};
typedef std::unordered_set<std::string> RequiredSet;
public:
enum DefinitionLevel {
Undefined,
PotentiallyDefined,
Defined,
};
typedef std::unordered_set<std::string> RequiredSet;
private:
std::unordered_map<CFGBlock*, std::unordered_map<std::string, DefinitionLevel> > results;
std::unordered_map<CFGBlock*, const RequiredSet> defined;
ScopeInfo *scope_info;
private:
std::unordered_map<CFGBlock*, std::unordered_map<std::string, DefinitionLevel> > results;
std::unordered_map<CFGBlock*, const RequiredSet> defined;
ScopeInfo* scope_info;
public:
DefinednessAnalysis(AST_arguments *args, CFG* cfg, ScopeInfo *scope_info);
public:
DefinednessAnalysis(AST_arguments* args, CFG* cfg, ScopeInfo* scope_info);
DefinitionLevel isDefinedAt(const std::string &name, CFGBlock *block);
const RequiredSet& getDefinedNamesAt(CFGBlock *block);
DefinitionLevel isDefinedAt(const std::string& name, CFGBlock* block);
const RequiredSet& getDefinedNamesAt(CFGBlock* block);
};
class PhiAnalysis {
public:
typedef std::unordered_set<std::string> RequiredSet;
public:
typedef std::unordered_set<std::string> RequiredSet;
private:
DefinednessAnalysis definedness;
LivenessAnalysis *liveness;
std::unordered_map<CFGBlock*, const RequiredSet> required_phis;
private:
DefinednessAnalysis definedness;
LivenessAnalysis* liveness;
std::unordered_map<CFGBlock*, const RequiredSet> required_phis;
public:
PhiAnalysis(AST_arguments*, CFG* cfg, LivenessAnalysis *liveness, ScopeInfo *scope_info);
public:
PhiAnalysis(AST_arguments*, CFG* cfg, LivenessAnalysis* liveness, ScopeInfo* scope_info);
bool isRequired(const std::string &name, CFGBlock* block);
bool isRequiredAfter(const std::string &name, CFGBlock* block);
const RequiredSet& getAllRequiredAfter(CFGBlock *block);
const RequiredSet& getAllDefinedAt(CFGBlock *block);
bool isPotentiallyUndefinedAfter(const std::string &name, CFGBlock* block);
bool isRequired(const std::string& name, CFGBlock* block);
bool isRequiredAfter(const std::string& name, CFGBlock* block);
const RequiredSet& getAllRequiredAfter(CFGBlock* block);
const RequiredSet& getAllDefinedAt(CFGBlock* block);
bool isPotentiallyUndefinedAfter(const std::string& name, CFGBlock* block);
};
LivenessAnalysis* computeLivenessInfo(CFG*);
PhiAnalysis* computeRequiredPhis(AST_arguments*, CFG*, LivenessAnalysis*, ScopeInfo* scope_Info);
}
#endif
This diff is collapsed.
......@@ -23,38 +23,36 @@ class AST;
class AST_Module;
class ScopeInfo {
public:
virtual ~ScopeInfo() {}
virtual ScopeInfo* getParent() = 0;
public:
virtual ~ScopeInfo() {}
virtual ScopeInfo* getParent() = 0;
virtual bool createsClosure() = 0;
virtual bool takesClosure() = 0;
virtual bool createsClosure() = 0;
virtual bool takesClosure() = 0;
virtual bool refersToGlobal(const std::string &name) = 0;
virtual bool refersToClosure(const std::string name) = 0;
virtual bool saveInClosure(const std::string name) = 0;
virtual bool refersToGlobal(const std::string& name) = 0;
virtual bool refersToClosure(const std::string name) = 0;
virtual bool saveInClosure(const std::string name) = 0;
};
class ScopingAnalysis {
public:
struct ScopeNameUsage;
typedef std::unordered_map<AST*, ScopeNameUsage*> NameUsageMap;
public:
struct ScopeNameUsage;
typedef std::unordered_map<AST*, ScopeNameUsage*> NameUsageMap;
private:
private:
std::unordered_map<AST*, ScopeInfo*> scopes;
AST_Module* parent_module;
std::unordered_map<AST*, ScopeInfo*> scopes;
AST_Module* parent_module;
ScopeInfo* analyzeSubtree(AST* node);
void processNameUsages(NameUsageMap* usages);
ScopeInfo* analyzeSubtree(AST* node);
void processNameUsages(NameUsageMap* usages);
public:
ScopingAnalysis(AST_Module *m);
ScopeInfo* getScopeInfoForNode(AST* node);
public:
ScopingAnalysis(AST_Module* m);
ScopeInfo* getScopeInfoForNode(AST* node);
};
ScopingAnalysis* runScopingAnalysis(AST_Module* m);
}
#endif
This diff is collapsed.
......@@ -26,22 +26,23 @@ namespace pyston {
class ScopeInfo;
class TypeAnalysis {
public:
enum SpeculationLevel {
NONE,
SOME,
};
public:
enum SpeculationLevel {
NONE,
SOME,
};
virtual ~TypeAnalysis() {}
virtual ~TypeAnalysis() {}
virtual ConcreteCompilerType* getTypeAtBlockStart(const std::string &name, CFGBlock* block) = 0;
virtual ConcreteCompilerType* getTypeAtBlockEnd(const std::string &name, CFGBlock* block) = 0;
virtual BoxedClass* speculatedExprClass(AST_expr*) = 0;
virtual ConcreteCompilerType* getTypeAtBlockStart(const std::string& name, CFGBlock* block) = 0;
virtual ConcreteCompilerType* getTypeAtBlockEnd(const std::string& name, CFGBlock* block) = 0;
virtual BoxedClass* speculatedExprClass(AST_expr*) = 0;
};
//TypeAnalysis* analyze(CFG *cfg, std::unordered_map<std::string, ConcreteCompilerType*> arg_types);
TypeAnalysis* doTypeAnalysis(CFG *cfg, const std::vector<AST_expr*> &arg_names, const std::vector<ConcreteCompilerType*> &arg_types, TypeAnalysis::SpeculationLevel speculation, ScopeInfo *scope_info);
// TypeAnalysis* analyze(CFG *cfg, std::unordered_map<std::string, ConcreteCompilerType*> arg_types);
TypeAnalysis* doTypeAnalysis(CFG* cfg, const std::vector<AST_expr*>& arg_names,
const std::vector<ConcreteCompilerType*>& arg_types,
TypeAnalysis::SpeculationLevel speculation, ScopeInfo* scope_info);
}
#endif
......@@ -22,22 +22,7 @@ namespace pyston {
namespace assembler {
const char* regnames[] = {
"rax",
"rcx",
"rdx",
"rbx",
"rsp",
"rbp",
"rsi",
"rdi",
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
"rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
};
void Register::dump() const {
......@@ -85,7 +70,7 @@ GenericRegister GenericRegister::fromDwarf(int dwarf_regnum) {
void Assembler::emitArith(Immediate imm, Register r, int opcode) {
//assert(r != RSP && "This breaks unwinding, please don't use.");
// assert(r != RSP && "This breaks unwinding, please don't use.");
int64_t amount = imm.val;
RELEASE_ASSERT(-0x80 <= amount && amount < 0x80 && "unsupported", "");
......@@ -142,7 +127,6 @@ void Assembler::emitSIB(uint8_t scalebits, uint8_t index, uint8_t base) {
void Assembler::mov(Immediate val, Register dest) {
int rex = REX_W;
......@@ -159,7 +143,7 @@ void Assembler::mov(Immediate val, Register dest) {
void Assembler::movq(Immediate src, Indirect dest) {
int64_t src_val = src.val;
assert((-1L<<31) <= src_val && src_val < (1L<<31)-1);
assert((-1L << 31) <= src_val && src_val < (1L << 31) - 1);
int rex = REX_W;
......@@ -418,7 +402,7 @@ void Assembler::movsd(Indirect src, XMMRegister dest) {
void Assembler::push(Register reg) {
//assert(0 && "This breaks unwinding, please don't use.");
// assert(0 && "This breaks unwinding, please don't use.");
assert(reg != RSP); // this might work but most likely a bug
......@@ -433,7 +417,7 @@ void Assembler::push(Register reg) {
}
void Assembler::pop(Register reg) {
//assert(0 && "This breaks unwinding, please don't use.");
// assert(0 && "This breaks unwinding, please don't use.");
assert(reg != RSP); // this might work but most likely a bug
......@@ -467,7 +451,6 @@ void Assembler::inc(Indirect mem) {
void Assembler::callq(Register r) {
assert(r == R11 && "untested");
......@@ -503,7 +486,7 @@ void Assembler::cmp(Register reg1, Register reg2) {
void Assembler::cmp(Register reg, Immediate imm) {
int64_t val = imm.val;
assert((-1L<<31) <= val && val < (1L<<31)-1);
assert((-1L << 31) <= val && val < (1L << 31) - 1);
int reg_idx = reg.regnum;
......@@ -522,7 +505,7 @@ void Assembler::cmp(Register reg, Immediate imm) {
void Assembler::cmp(Indirect mem, Immediate imm) {
int64_t val = imm.val;
assert((-1L<<31) <= val && val < (1L<<31)-1);
assert((-1L << 31) <= val && val < (1L << 31) - 1);
int src_idx = mem.base.regnum;
......@@ -607,7 +590,8 @@ void Assembler::jmp_cond(JumpDestination dest, ConditionCode condition) {
assert(dest.type == JumpDestination::FROM_START);
int offset = dest.offset - (addr - start_addr) - 2;
if (unlikely) offset--;
if (unlikely)
offset--;
if (offset >= -0x80 && offset < 0x80) {
if (unlikely)
......@@ -681,11 +665,11 @@ uint8_t* Assembler::emitCall(void* ptr, Register scratch) {
return addr;
}
void Assembler::emitBatchPush(StackInfo stack_info, const std::vector<GenericRegister> &to_push) {
void Assembler::emitBatchPush(StackInfo stack_info, const std::vector<GenericRegister>& to_push) {
assert(stack_info.has_scratch);
int offset = 0;
for (const GenericRegister &r : to_push) {
for (const GenericRegister& r : to_push) {
assert(stack_info.scratch_bytes >= offset + 8);
Indirect next_slot(RBP, offset + stack_info.scratch_rbp_offset);
......@@ -704,11 +688,11 @@ void Assembler::emitBatchPush(StackInfo stack_info, const std::vector<GenericReg
}
}
void Assembler::emitBatchPop(StackInfo stack_info, const std::vector<GenericRegister> &to_push) {
void Assembler::emitBatchPop(StackInfo stack_info, const std::vector<GenericRegister>& to_push) {
assert(stack_info.has_scratch);
int offset = 0;
for (const GenericRegister &r : to_push) {
for (const GenericRegister& r : to_push) {
assert(stack_info.scratch_bytes >= offset + 8);
Indirect next_slot(RBP, offset + stack_info.scratch_rbp_offset);
......@@ -747,16 +731,17 @@ void Assembler::emitAnnotation(int num) {
uint8_t* initializePatchpoint2(uint8_t* start_addr, uint8_t* slowpath_start, uint8_t* end_addr, StackInfo stack_info, const std::unordered_set<int> &live_outs) {
uint8_t* initializePatchpoint2(uint8_t* start_addr, uint8_t* slowpath_start, uint8_t* end_addr, StackInfo stack_info,
const std::unordered_set<int>& live_outs) {
assert(start_addr < slowpath_start);
static const int INITIAL_CALL_SIZE = 13;
assert(end_addr > slowpath_start + INITIAL_CALL_SIZE);
#ifndef NDEBUG
//if (VERBOSITY()) printf("initializing patchpoint at %p - %p\n", addr, addr + size);
//for (int i = 0; i < size; i++) {
//printf("%02x ", *(addr + i));
// if (VERBOSITY()) printf("initializing patchpoint at %p - %p\n", addr, addr + size);
// for (int i = 0; i < size; i++) {
// printf("%02x ", *(addr + i));
//}
//printf("\n");
// printf("\n");
// Check the exact form of the patchpoint call.
// It's important to make sure that the only live registers
......@@ -800,8 +785,8 @@ uint8_t* initializePatchpoint2(uint8_t* start_addr, uint8_t* slowpath_start, uin
Assembler assem(slowpath_start, end_addr - slowpath_start);
//if (regs_to_spill.size())
//assem.trap();
// if (regs_to_spill.size())
// assem.trap();
assem.emitBatchPush(stack_info, regs_to_spill);
uint8_t* rtn = assem.emitCall(call_addr, R11);
assem.emitBatchPop(stack_info, regs_to_spill);
......@@ -809,6 +794,5 @@ uint8_t* initializePatchpoint2(uint8_t* start_addr, uint8_t* slowpath_start, uin
return rtn;
}
}
}
......@@ -27,102 +27,103 @@ namespace assembler {
class BoxedClass;
enum ConditionCode {
COND_OVERFLOW = 0, // OF=1: O
COND_NOT_OVERFLOW = 1, // OF=0: NO
COND_OVERFLOW = 0, // OF=1: O
COND_NOT_OVERFLOW = 1, // OF=0: NO
// next 4 are unsigned:
COND_BELOW = 2, // CF=1: B/NAE/C
COND_NOT_BELOW = 3, // CF=0: NB/AE/C
COND_EQUAL = 4, // ZF=0: Z/E
COND_NOT_EQUAL = 5, // ZF=1: NZ/NE
COND_BELOW = 2, // CF=1: B/NAE/C
COND_NOT_BELOW = 3, // CF=0: NB/AE/C
COND_EQUAL = 4, // ZF=0: Z/E
COND_NOT_EQUAL = 5, // ZF=1: NZ/NE
COND_NOT_ZERO = 5, // ZF=1: NZ/NE
COND_NOT_ABOVE = 6, // CF=1: ZF=1: BE/NA
COND_ABOVE = 7, // CF=0: ZF=0: NBE/A
COND_SIGN = 8, // SF=1: S
COND_NOT_SIGN = 9, // SF=0: NS
COND_PARITY_EVEN = 0xA, // PF=1: P/PE
COND_PARITY_ODD = 0xB, // PF=0: NP/PO
COND_NOT_ABOVE = 6, // CF=1: ZF=1: BE/NA
COND_ABOVE = 7, // CF=0: ZF=0: NBE/A
COND_SIGN = 8, // SF=1: S
COND_NOT_SIGN = 9, // SF=0: NS
COND_PARITY_EVEN = 0xA, // PF=1: P/PE
COND_PARITY_ODD = 0xB, // PF=0: NP/PO
// next 4 are signed:
COND_LESS = 0xC, // SF!=OF: L/NGE
COND_NOT_LESS = 0xD, // SF==OF: NL/GE
COND_NOT_GREATER = 0xE, // ZF=1 || SF!=OF: LE/NG
COND_GREATER = 0xF, // ZF=0 && SF==OF: NLE/G
COND_LESS = 0xC, // SF!=OF: L/NGE
COND_NOT_LESS = 0xD, // SF==OF: NL/GE
COND_NOT_GREATER = 0xE, // ZF=1 || SF!=OF: LE/NG
COND_GREATER = 0xF, // ZF=0 && SF==OF: NLE/G
};
class Assembler {
private:
uint8_t *const start_addr, *const end_addr;
uint8_t *addr;
static const uint8_t OPCODE_ADD = 0b000, OPCODE_SUB = 0b101;
static const uint8_t REX_B = 1, REX_X = 2, REX_R = 4, REX_W = 8;
private:
void emitByte(uint8_t b);
void emitInt(int64_t n, int bytes);
void emitRex(uint8_t rex);
void emitModRM(uint8_t mod, uint8_t reg, uint8_t rm);
void emitSIB(uint8_t scalebits, uint8_t index, uint8_t base);
void emitArith(Immediate imm, Register reg, int opcode);
public:
Assembler(uint8_t* start, int size) : start_addr(start), end_addr(start + size), addr(start_addr) {}
void nop() { emitByte(0x90); }
void trap() { emitByte(0xcc); }
// some things (such as objdump) call this "movabs" if the immediate is 64-bit
void mov(Immediate imm, Register dest);
// not sure if we should use the 'q' suffix here, but this is the most ambiguous one;
// this does a 64-bit store of a 32-bit value.
void movq(Immediate imm, Indirect dest);
void mov(Register src, Register dest);
void mov(Register src, Indirect dest);
void mov(Indirect src, Register dest);
void movsd(XMMRegister src, XMMRegister dest);
void movsd(XMMRegister src, Indirect dest);
void movsd(Indirect src, XMMRegister dest);
void push(Register reg);
void pop(Register reg);
void add(Immediate imm, Register reg);
void sub(Immediate imm, Register reg);
void inc(Register reg);
void inc(Indirect mem);
void callq(Register reg);
void cmp(Register reg1, Register reg2);
void cmp(Register reg, Immediate imm);
void cmp(Indirect mem, Immediate imm);
void cmp(Indirect mem, Register reg);
void test(Register reg1, Register reg2);
void jmp_cond(JumpDestination dest, ConditionCode condition);
void jmp(JumpDestination dest);
void je(JumpDestination dest);
void jne(JumpDestination dest);
void set_cond(Register reg, ConditionCode condition);
void sete(Register reg);
void setz(Register reg) { sete(reg); }
void setne(Register reg);
void setnz(Register reg) { setne(reg); }
// Macros:
uint8_t* emitCall(void* func_addr, Register scratch);
void emitBatchPop(StackInfo stack_info, const std::vector<GenericRegister> &to_push);
void emitBatchPush(StackInfo stack_info, const std::vector<GenericRegister> &to_push);
void fillWithNops();
void fillWithNopsExcept(int bytes);
void emitAnnotation(int num);
bool isExactlyFull() { return addr == end_addr; }
private:
uint8_t* const start_addr, *const end_addr;
uint8_t* addr;
static const uint8_t OPCODE_ADD = 0b000, OPCODE_SUB = 0b101;
static const uint8_t REX_B = 1, REX_X = 2, REX_R = 4, REX_W = 8;
private:
void emitByte(uint8_t b);
void emitInt(int64_t n, int bytes);
void emitRex(uint8_t rex);
void emitModRM(uint8_t mod, uint8_t reg, uint8_t rm);
void emitSIB(uint8_t scalebits, uint8_t index, uint8_t base);
void emitArith(Immediate imm, Register reg, int opcode);
public:
Assembler(uint8_t* start, int size) : start_addr(start), end_addr(start + size), addr(start_addr) {}
void nop() { emitByte(0x90); }
void trap() { emitByte(0xcc); }
// some things (such as objdump) call this "movabs" if the immediate is 64-bit
void mov(Immediate imm, Register dest);
// not sure if we should use the 'q' suffix here, but this is the most ambiguous one;
// this does a 64-bit store of a 32-bit value.
void movq(Immediate imm, Indirect dest);
void mov(Register src, Register dest);
void mov(Register src, Indirect dest);
void mov(Indirect src, Register dest);
void movsd(XMMRegister src, XMMRegister dest);
void movsd(XMMRegister src, Indirect dest);
void movsd(Indirect src, XMMRegister dest);
void push(Register reg);
void pop(Register reg);
void add(Immediate imm, Register reg);
void sub(Immediate imm, Register reg);
void inc(Register reg);
void inc(Indirect mem);
void callq(Register reg);
void cmp(Register reg1, Register reg2);
void cmp(Register reg, Immediate imm);
void cmp(Indirect mem, Immediate imm);
void cmp(Indirect mem, Register reg);
void test(Register reg1, Register reg2);
void jmp_cond(JumpDestination dest, ConditionCode condition);
void jmp(JumpDestination dest);
void je(JumpDestination dest);
void jne(JumpDestination dest);
void set_cond(Register reg, ConditionCode condition);
void sete(Register reg);
void setz(Register reg) { sete(reg); }
void setne(Register reg);
void setnz(Register reg) { setne(reg); }
// Macros:
uint8_t* emitCall(void* func_addr, Register scratch);
void emitBatchPop(StackInfo stack_info, const std::vector<GenericRegister>& to_push);
void emitBatchPush(StackInfo stack_info, const std::vector<GenericRegister>& to_push);
void fillWithNops();
void fillWithNopsExcept(int bytes);
void emitAnnotation(int num);
bool isExactlyFull() { return addr == end_addr; }
};
uint8_t* initializePatchpoint2(uint8_t* start_addr, uint8_t* slowpath_start, uint8_t* end_addr, StackInfo stack_info, const std::unordered_set<int> &live_outs);
uint8_t* initializePatchpoint2(uint8_t* start_addr, uint8_t* slowpath_start, uint8_t* end_addr, StackInfo stack_info,
const std::unordered_set<int>& live_outs);
}
}
......
......@@ -59,7 +59,8 @@ ICSlotRewrite::ICSlotRewrite(ICInfo* ic, const char* debug_name) : ic(ic), debug
assembler = new Assembler(buf, ic->getSlotSize());
assembler->nop();
if (VERBOSITY()) printf("starting %s icentry\n", debug_name);
if (VERBOSITY())
printf("starting %s icentry\n", debug_name);
}
ICSlotRewrite::~ICSlotRewrite() {
......@@ -67,27 +68,28 @@ ICSlotRewrite::~ICSlotRewrite() {
free(buf);
}
void ICSlotRewrite::commit(uint64_t decision_path, CommitHook *hook) {
void ICSlotRewrite::commit(uint64_t decision_path, CommitHook* hook) {
bool still_valid = true;
for (int i = 0; i < dependencies.size(); i++) {
int orig_version = dependencies[i].second;
ICInvalidator *invalidator = dependencies[i].first;
ICInvalidator* invalidator = dependencies[i].first;
if (orig_version != invalidator->version()) {
still_valid = false;
break;
}
}
if (!still_valid) {
if (VERBOSITY()) printf("not committing %s icentry since a dependency got updated before commit\n", debug_name);
if (VERBOSITY())
printf("not committing %s icentry since a dependency got updated before commit\n", debug_name);
return;
}
ICSlotInfo *ic_entry = ic->pickEntryForRewrite(decision_path, debug_name);
ICSlotInfo* ic_entry = ic->pickEntryForRewrite(decision_path, debug_name);
if (ic_entry == NULL)
return;
for (int i = 0; i < dependencies.size(); i++) {
ICInvalidator *invalidator = dependencies[i].first;
ICInvalidator* invalidator = dependencies[i].first;
invalidator->addDependent(ic_entry);
}
......@@ -98,13 +100,13 @@ void ICSlotRewrite::commit(uint64_t decision_path, CommitHook *hook) {
assert(assembler->isExactlyFull());
//if (VERBOSITY()) printf("Commiting to %p-%p\n", start, start + ic->slot_size);
// if (VERBOSITY()) printf("Commiting to %p-%p\n", start, start + ic->slot_size);
memcpy(slot_start, buf, ic->getSlotSize());
llvm::sys::Memory::InvalidateInstructionCache(slot_start, ic->getSlotSize());
}
void ICSlotRewrite::addDependenceOn(ICInvalidator &invalidator) {
void ICSlotRewrite::addDependenceOn(ICInvalidator& invalidator) {
dependencies.push_back(std::make_pair(&invalidator, invalidator.version()));
}
......@@ -144,7 +146,7 @@ ICSlotRewrite* ICInfo::startRewrite(const char* debug_name) {
ICSlotInfo* ICInfo::pickEntryForRewrite(uint64_t decision_path, const char* debug_name) {
for (int i = 0; i < getNumSlots(); i++) {
SlotInfo &sinfo = slots[i];
SlotInfo& sinfo = slots[i];
if (!sinfo.is_patched) {
if (VERBOSITY()) {
printf("committing %s icentry to unused slot %d at %p\n", debug_name, i, start_addr);
......@@ -160,7 +162,7 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(uint64_t decision_path, const char* debu
for (int _i = 0; _i < num_slots; _i++) {
int i = (_i + next_slot_to_try) % num_slots;
SlotInfo &sinfo = slots[i];
SlotInfo& sinfo = slots[i];
if (sinfo.is_patched && sinfo.decision_path != decision_path) {
continue;
}
......@@ -174,20 +176,27 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(uint64_t decision_path, const char* debu
sinfo.decision_path = decision_path;
return &sinfo.entry;
}
if (VERBOSITY()) printf("not committing %s icentry since it is not compatible (%lx)\n", debug_name, decision_path);
if (VERBOSITY())
printf("not committing %s icentry since it is not compatible (%lx)\n", debug_name, decision_path);
return NULL;
}
ICInfo::ICInfo(void* start_addr, void* continue_addr, StackInfo stack_info, int num_slots, int slot_size, llvm::CallingConv::ID calling_conv, const std::unordered_set<int> &live_outs, assembler::GenericRegister return_register, TypeRecorder *type_recorder) : next_slot_to_try(0), stack_info(stack_info), num_slots(num_slots), slot_size(slot_size), calling_conv(calling_conv), live_outs(live_outs.begin(), live_outs.end()), return_register(return_register), type_recorder(type_recorder), start_addr(start_addr), continue_addr(continue_addr) {
ICInfo::ICInfo(void* start_addr, void* continue_addr, StackInfo stack_info, int num_slots, int slot_size,
llvm::CallingConv::ID calling_conv, const std::unordered_set<int>& live_outs,
assembler::GenericRegister return_register, TypeRecorder* type_recorder)
: next_slot_to_try(0), stack_info(stack_info), num_slots(num_slots), slot_size(slot_size),
calling_conv(calling_conv), live_outs(live_outs.begin(), live_outs.end()), return_register(return_register),
type_recorder(type_recorder), start_addr(start_addr), continue_addr(continue_addr) {
for (int i = 0; i < num_slots; i++) {
slots.push_back(SlotInfo(this, i));
}
}
static std::unordered_map<void*, ICInfo*> ics_by_return_addr;
void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo* pp, StackInfo stack_info, std::unordered_set<int> live_outs) {
void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo* pp, StackInfo stack_info,
std::unordered_set<int> live_outs) {
int size = pp->totalSize();
uint8_t* end_addr = start_addr + size;
uint8_t* slowpath_addr = end_addr;
......@@ -195,7 +204,8 @@ void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo* pp, St
uint8_t* rtn_addr;
assembler::GenericRegister return_register;
assert(pp->getCallingConvention() == llvm::CallingConv::C || pp->getCallingConvention() == llvm::CallingConv::PreserveAll);
assert(pp->getCallingConvention() == llvm::CallingConv::C || pp->getCallingConvention()
== llvm::CallingConv::PreserveAll);
if (pp->hasReturnValue()) {
static const int DWARF_RAX = 0;
// It's possible that the return value doesn't get used, in which case
......@@ -213,13 +223,14 @@ void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo* pp, St
uint8_t* slowpath_start = start_addr + pp->num_slots * pp->slot_size;
rtn_addr = initializePatchpoint2(start_addr, slowpath_start, (uint8_t*)end_addr, stack_info, live_outs);
} else {
//for (int regnum : live_outs) {
//// LLVM has a bug where it incorrectly determines the set of liveouts;
//// so far it only seems to add additional ones to the set, which should
//// hopefully be safe.
//// Otherwise, I'd like to test here that it's only the registers
//// that we'd expect to be saved...
//ASSERT(regnum == 0 || regnum == 3 || regnum == 6 || regnum == 12 || regnum == 13 || regnum == 14 || regnum == 15 || regnum == 7, "%d", regnum);
// for (int regnum : live_outs) {
//// LLVM has a bug where it incorrectly determines the set of liveouts;
//// so far it only seems to add additional ones to the set, which should
//// hopefully be safe.
//// Otherwise, I'd like to test here that it's only the registers
//// that we'd expect to be saved...
// ASSERT(regnum == 0 || regnum == 3 || regnum == 6 || regnum == 12 || regnum == 13 || regnum == 14 || regnum ==
// 15 || regnum == 7, "%d", regnum);
//}
initializePatchpoint(start_addr, size);
......@@ -231,17 +242,19 @@ void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo* pp, St
// Not sure if this is worth it or not?
for (int i = 0; i < pp->num_slots; i++) {
uint8_t* start = start_addr + i * pp->slot_size;
//std::unique_ptr<MCWriter> writer(createMCWriter(start, pp->slot_size * (pp->num_slots - i), 0));
//writer->emitNop();
//writer->emitGuardFalse();
// std::unique_ptr<MCWriter> writer(createMCWriter(start, pp->slot_size * (pp->num_slots - i), 0));
// writer->emitNop();
// writer->emitGuardFalse();
std::unique_ptr<Assembler> writer(new Assembler(start, pp->slot_size));
writer->nop();
//writer->trap();
// writer->trap();
writer->jmp(JumpDestination::fromStart(pp->slot_size * (pp->num_slots - i)));
}
ics_by_return_addr[rtn_addr] = new ICInfo(start_addr, slowpath_addr, stack_info, pp->num_slots, pp->slot_size, pp->getCallingConvention(), live_outs, return_register, pp->type_recorder);
ics_by_return_addr[rtn_addr]
= new ICInfo(start_addr, slowpath_addr, stack_info, pp->num_slots, pp->slot_size, pp->getCallingConvention(),
live_outs, return_register, pp->type_recorder);
}
ICInfo* getICInfo(void* rtn_addr) {
......@@ -256,17 +269,17 @@ void ICInfo::clear(ICSlotInfo* icentry) {
uint8_t* start = (uint8_t*)start_addr + icentry->idx * getSlotSize();
if (VERBOSITY()) printf("clearing patchpoint %p, slot at %p\n", start_addr, start);
if (VERBOSITY())
printf("clearing patchpoint %p, slot at %p\n", start_addr, start);
std::unique_ptr<Assembler> writer(new Assembler(start, getSlotSize()));
writer->nop();
writer->jmp(JumpDestination::fromStart(getSlotSize()));
//std::unique_ptr<MCWriter> writer(createMCWriter(start, getSlotSize(), 0));
//writer->emitNop();
//writer->emitGuardFalse();
// std::unique_ptr<MCWriter> writer(createMCWriter(start, getSlotSize(), 0));
// writer->emitNop();
// writer->emitGuardFalse();
//writer->endWithSlowpath();
// writer->endWithSlowpath();
llvm::sys::Memory::InvalidateInstructionCache(start, getSlotSize());
}
}
......@@ -30,102 +30,104 @@ class ICInfo;
class ICInvalidator;
struct ICSlotInfo {
public:
ICSlotInfo(ICInfo* ic, int idx) : ic(ic), idx(idx) {}
public:
ICSlotInfo(ICInfo* ic, int idx) : ic(ic), idx(idx) {}
ICInfo *ic;
int idx;
ICInfo* ic;
int idx;
void clear();
void clear();
};
class ICSlotRewrite {
public:
class CommitHook {
public:
class CommitHook {
public:
virtual ~CommitHook() {}
virtual void finishAssembly(int fastpath_offset) = 0;
};
private:
ICInfo* ic;
assembler::Assembler* assembler;
const char* debug_name;
virtual ~CommitHook() {}
virtual void finishAssembly(int fastpath_offset) = 0;
};
uint8_t *buf;
private:
ICInfo* ic;
assembler::Assembler* assembler;
const char* debug_name;
std::vector<std::pair<ICInvalidator*, int64_t> > dependencies;
uint8_t* buf;
ICSlotRewrite(ICInfo* ic, const char* debug_name);
std::vector<std::pair<ICInvalidator*, int64_t> > dependencies;
public:
~ICSlotRewrite();
ICSlotRewrite(ICInfo* ic, const char* debug_name);
public:
~ICSlotRewrite();
assembler::Assembler* getAssembler() { return assembler; }
int getSlotSize();
int getFuncStackSize();
int getScratchRbpOffset();
int getScratchBytes();
assembler::Assembler* getAssembler() { return assembler; }
int getSlotSize();
int getFuncStackSize();
int getScratchRbpOffset();
int getScratchBytes();
TypeRecorder* getTypeRecorder();
TypeRecorder* getTypeRecorder();
assembler::GenericRegister returnRegister();
assembler::GenericRegister returnRegister();
void addDependenceOn(ICInvalidator&);
void commit(uint64_t decision_path, CommitHook *hook);
void addDependenceOn(ICInvalidator&);
void commit(uint64_t decision_path, CommitHook* hook);
friend class ICInfo;
friend class ICInfo;
};
class ICInfo {
private:
struct SlotInfo {
bool is_patched;
uint64_t decision_path;
ICSlotInfo entry;
SlotInfo(ICInfo* ic, int idx) : is_patched(false), decision_path(0), entry(ic, idx) {}
};
std::vector<SlotInfo> slots;
// For now, just use a round-robin eviction policy.
// This is probably a bunch worse than LRU, but it's also
// probably a bunch better than the "always evict slot #0" policy
// that it's replacing.
int next_slot_to_try;
const StackInfo stack_info;
const int num_slots;
const int slot_size;
const llvm::CallingConv::ID calling_conv;
const std::vector<int> live_outs;
const assembler::GenericRegister return_register;
TypeRecorder * const type_recorder;
// for ICSlotRewrite:
ICSlotInfo *pickEntryForRewrite(uint64_t decision_path, const char* debug_name);
void* getSlowpathStart();
public:
ICInfo(void* start_addr, void* continue_addr, StackInfo stack_info, int num_slots, int slot_size, llvm::CallingConv::ID calling_conv, const std::unordered_set<int> &live_outs, assembler::GenericRegister return_register, TypeRecorder *type_recorder);
void *const start_addr, *const continue_addr;
int getSlotSize() { return slot_size; }
int getNumSlots() { return num_slots; }
llvm::CallingConv::ID getCallingConvention() { return calling_conv; }
const std::vector<int>& getLiveOuts() { return live_outs; }
ICSlotRewrite* startRewrite(const char* debug_name);
void clear(ICSlotInfo *entry);
friend class ICSlotRewrite;
private:
struct SlotInfo {
bool is_patched;
uint64_t decision_path;
ICSlotInfo entry;
SlotInfo(ICInfo* ic, int idx) : is_patched(false), decision_path(0), entry(ic, idx) {}
};
std::vector<SlotInfo> slots;
// For now, just use a round-robin eviction policy.
// This is probably a bunch worse than LRU, but it's also
// probably a bunch better than the "always evict slot #0" policy
// that it's replacing.
int next_slot_to_try;
const StackInfo stack_info;
const int num_slots;
const int slot_size;
const llvm::CallingConv::ID calling_conv;
const std::vector<int> live_outs;
const assembler::GenericRegister return_register;
TypeRecorder* const type_recorder;
// for ICSlotRewrite:
ICSlotInfo* pickEntryForRewrite(uint64_t decision_path, const char* debug_name);
void* getSlowpathStart();
public:
ICInfo(void* start_addr, void* continue_addr, StackInfo stack_info, int num_slots, int slot_size,
llvm::CallingConv::ID calling_conv, const std::unordered_set<int>& live_outs,
assembler::GenericRegister return_register, TypeRecorder* type_recorder);
void* const start_addr, *const continue_addr;
int getSlotSize() { return slot_size; }
int getNumSlots() { return num_slots; }
llvm::CallingConv::ID getCallingConvention() { return calling_conv; }
const std::vector<int>& getLiveOuts() { return live_outs; }
ICSlotRewrite* startRewrite(const char* debug_name);
void clear(ICSlotInfo* entry);
friend class ICSlotRewrite;
};
class PatchpointSetupInfo;
void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo*, StackInfo stack_info, std::unordered_set<int> live_outs);
void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo*, StackInfo stack_info,
std::unordered_set<int> live_outs);
ICInfo* getICInfo(void* rtn_addr);
}
#endif
This diff is collapsed.
......@@ -22,40 +22,38 @@ namespace pyston {
class BoxedClass;
class MCWriter {
public:
virtual ~MCWriter() {}
virtual int numArgRegs() = 0;
virtual int numTempRegs() = 0;
// TODO I don't like this method, could be broken down into simpler things
virtual void emitAlloca(int bytes, int dest_argnum) = 0;
virtual void emitNop() = 0;
virtual void emitTrap() = 0;
virtual void emitAnnotation(int num) = 0;
virtual void endFastPath(void* success_dest, void* will_relocate_to) = 0;
virtual void endWithSlowpath() = 0;
virtual uint8_t* emitCall(void* target, int npushes) = 0;
virtual void emitGuardFalse() = 0;
virtual void emitAttrGuard(int argnum, int offset, int64_t val, int npops) = 0;
virtual void emitGuard(int argnum, int64_t val, int npops) = 0;
virtual void emitGuardNotEq(int argnum, int64_t val, int npops) = 0;
virtual void emitMove(int src_argnum, int dest_argnum, int npushed) = 0;
virtual void emitSetattr(int src_argnum, int dest_argnum, int dest_offset) = 0;
virtual void emitGetattr(int src_argnum, int src_offset, int dest_argnum) = 0;
virtual void emitIncattr(int argnum, int offset) = 0;
virtual void emitPush(int reg) = 0;
virtual void emitPop(int reg) = 0;
virtual void emitLoadConst(int reg, int64_t value) = 0;
virtual void emitCmp(AST_TYPE::AST_TYPE cmp_type, int lhs_argnum, int rhs_argnum, int dest_argnum) = 0;
virtual void emitToBool(int argnum, int dest_argnum) = 0;
public:
virtual ~MCWriter() {}
virtual int numArgRegs() = 0;
virtual int numTempRegs() = 0;
// TODO I don't like this method, could be broken down into simpler things
virtual void emitAlloca(int bytes, int dest_argnum) = 0;
virtual void emitNop() = 0;
virtual void emitTrap() = 0;
virtual void emitAnnotation(int num) = 0;
virtual void endFastPath(void* success_dest, void* will_relocate_to) = 0;
virtual void endWithSlowpath() = 0;
virtual uint8_t* emitCall(void* target, int npushes) = 0;
virtual void emitGuardFalse() = 0;
virtual void emitAttrGuard(int argnum, int offset, int64_t val, int npops) = 0;
virtual void emitGuard(int argnum, int64_t val, int npops) = 0;
virtual void emitGuardNotEq(int argnum, int64_t val, int npops) = 0;
virtual void emitMove(int src_argnum, int dest_argnum, int npushed) = 0;
virtual void emitSetattr(int src_argnum, int dest_argnum, int dest_offset) = 0;
virtual void emitGetattr(int src_argnum, int src_offset, int dest_argnum) = 0;
virtual void emitIncattr(int argnum, int offset) = 0;
virtual void emitPush(int reg) = 0;
virtual void emitPop(int reg) = 0;
virtual void emitLoadConst(int reg, int64_t value) = 0;
virtual void emitCmp(AST_TYPE::AST_TYPE cmp_type, int lhs_argnum, int rhs_argnum, int dest_argnum) = 0;
virtual void emitToBool(int argnum, int dest_argnum) = 0;
};
void initializePatchpoint(uint8_t* addr, int size);
MCWriter* createMCWriter(uint8_t* addr, int size, int num_temp_regs);
}
#endif
......@@ -50,11 +50,12 @@ Register fromArgnum(int argnum) {
RELEASE_ASSERT(0, "%d", argnum);
}
RewriterVar::RewriterVar(Rewriter *rewriter, int argnum, int version) : rewriter(rewriter), argnum(argnum), version(version) {
//assert(rewriter.icentry.get());
RewriterVar::RewriterVar(Rewriter* rewriter, int argnum, int version)
: rewriter(rewriter), argnum(argnum), version(version) {
// assert(rewriter.icentry.get());
}
RewriterVar& RewriterVar::operator=(const RewriterVar &rhs) {
RewriterVar& RewriterVar::operator=(const RewriterVar& rhs) {
assert(rewriter == NULL || rewriter == rhs.rewriter);
rhs.assertValid();
rewriter = rhs.rewriter;
......@@ -81,7 +82,7 @@ void RewriterVar::unlock() {
#endif
int RewriterVar::getArgnum() {
//assert(rewriter);
// assert(rewriter);
return argnum;
}
......@@ -128,7 +129,7 @@ RewriterVar RewriterVar::move(int dest_argnum) {
rewriter->assembler->mov(Indirect(RSP, offset), fromArgnum(dest_argnum));
} else {
int stack_size = rewriter->rewrite->getFuncStackSize();
ASSERT(stack_size > 0 && stack_size < (1<<30), "%d", stack_size);
ASSERT(stack_size > 0 && stack_size < (1 << 30), "%d", stack_size);
int offset = (this->argnum - 6) * 8 - (stack_size - 8);
rewriter->assembler->mov(Indirect(RBP, offset), fromArgnum(dest_argnum));
}
......@@ -151,7 +152,7 @@ void RewriterVar::addGuard(intptr_t val) {
int bytes = 8 * rewriter->pushes.size() + rewriter->alloca_bytes;
if (val < (-1L<<31) || val >= (1L<<31) - 1) {
if (val < (-1L << 31) || val >= (1L << 31) - 1) {
rewriter->assembler->push(RBP);
rewriter->assembler->mov(Immediate(val), RBP);
rewriter->assembler->cmp(fromArgnum(this->argnum), RBP);
......@@ -159,7 +160,7 @@ void RewriterVar::addGuard(intptr_t val) {
} else {
rewriter->assembler->cmp(fromArgnum(this->argnum), Immediate(val));
}
rewriter->assembler->jne(JumpDestination::fromStart(rewriter->rewrite->getSlotSize() - bytes/8));
rewriter->assembler->jne(JumpDestination::fromStart(rewriter->rewrite->getSlotSize() - bytes / 8));
}
void RewriterVar::addAttrGuard(int offset, intptr_t val) {
......@@ -170,7 +171,7 @@ void RewriterVar::addAttrGuard(int offset, intptr_t val) {
int bytes = 8 * rewriter->pushes.size() + rewriter->alloca_bytes;
if (val < (-1L<<31) || val >= (1L<<31) - 1) {
if (val < (-1L << 31) || val >= (1L << 31) - 1) {
rewriter->assembler->push(RBP);
rewriter->assembler->mov(Immediate(val), RBP);
rewriter->assembler->cmp(Indirect(fromArgnum(this->argnum), offset), RBP);
......@@ -178,7 +179,7 @@ void RewriterVar::addAttrGuard(int offset, intptr_t val) {
} else {
rewriter->assembler->cmp(Indirect(fromArgnum(this->argnum), offset), Immediate(val));
}
rewriter->assembler->jne(JumpDestination::fromStart(rewriter->rewrite->getSlotSize() - bytes/8));
rewriter->assembler->jne(JumpDestination::fromStart(rewriter->rewrite->getSlotSize() - bytes / 8));
}
void RewriterVar::addGuardNotEq(intptr_t val) {
......@@ -189,7 +190,7 @@ void RewriterVar::addGuardNotEq(intptr_t val) {
int bytes = 8 * rewriter->pushes.size() + rewriter->alloca_bytes;
rewriter->assembler->cmp(fromArgnum(this->argnum), Immediate(val));
rewriter->assembler->je(JumpDestination::fromStart(rewriter->rewrite->getSlotSize() - bytes/8));
rewriter->assembler->je(JumpDestination::fromStart(rewriter->rewrite->getSlotSize() - bytes / 8));
}
bool RewriterVar::isInReg() {
......@@ -205,7 +206,7 @@ void RewriterVar::push() {
rewriter->addPush(this->version);
}
RewriterVar RewriterVar::cmp(AST_TYPE::AST_TYPE cmp_type, const RewriterVar &val, int dest) {
RewriterVar RewriterVar::cmp(AST_TYPE::AST_TYPE cmp_type, const RewriterVar& val, int dest) {
assertValid();
rewriter->assembler->cmp(fromArgnum(this->argnum), fromArgnum(val.argnum));
......@@ -239,7 +240,7 @@ Rewriter* Rewriter::createRewriter(void* ic_rtn_addr, int num_orig_args, int num
static StatCounter rewriter_nopatch("rewriter_nopatch");
ICInfo *ic = getICInfo(ic_rtn_addr);
ICInfo* ic = getICInfo(ic_rtn_addr);
if (ic == NULL) {
rewriter_nopatch.log();
return NULL;
......@@ -249,21 +250,22 @@ Rewriter* Rewriter::createRewriter(void* ic_rtn_addr, int num_orig_args, int num
return new Rewriter(ic->startRewrite(debug_name), num_orig_args, num_temp_regs);
}
Rewriter::Rewriter(ICSlotRewrite* rewrite, int num_orig_args, int num_temp_regs) :
rewrite(rewrite), assembler(rewrite->getAssembler()),
num_orig_args(num_orig_args), num_temp_regs(num_temp_regs), alloca_bytes(0), max_pushes(0)
Rewriter::Rewriter(ICSlotRewrite* rewrite, int num_orig_args, int num_temp_regs)
: rewrite(rewrite), assembler(rewrite->getAssembler()), num_orig_args(num_orig_args), num_temp_regs(num_temp_regs),
alloca_bytes(0), max_pushes(0)
#ifndef NDEBUG
, next_version(2), changed_something(false)
,
next_version(2), changed_something(false)
#endif
, ndecisions(0), decision_path(1)
{
,
ndecisions(0), decision_path(1) {
//printf("trapping here\n");
//assembler->trap();
// printf("trapping here\n");
// assembler->trap();
//for (int i = 0; i < num_temp_regs; i++) {
//icentry->push(-2 - i);
//}
// for (int i = 0; i < num_temp_regs; i++) {
// icentry->push(-2 - i);
//}
#ifndef NDEBUG
for (int i = -3; i < MAX_ARGS; i++) {
......@@ -279,7 +281,7 @@ void Rewriter::addPush(int version) {
RewriterVar Rewriter::alloca_(int bytes, int dest_argnum) {
// TODO should check to make sure we aren't crossing push+pops and allocas
//printf("alloca()ing %d bytes\n", bytes);
// printf("alloca()ing %d bytes\n", bytes);
assert(bytes % sizeof(void*) == 0);
alloca_bytes += bytes;
......@@ -314,7 +316,7 @@ int Rewriter::mutate(int argnum) {
assert(versions.count(argnum));
int rtn_version = ++next_version;
//printf("mutating %d to %d\n", argnum, rtn_version);
// printf("mutating %d to %d\n", argnum, rtn_version);
versions[argnum] = rtn_version;
return rtn_version;
}
......@@ -357,7 +359,7 @@ RewriterVar Rewriter::call(void* func_addr) {
#ifndef NDEBUG
changed_something = true;
#endif
//printf("%ld pushes, %d alloca bytes\n", pushes.size(), alloca_bytes);
// printf("%ld pushes, %d alloca bytes\n", pushes.size(), alloca_bytes);
int bytes = 8 * pushes.size() + alloca_bytes;
bool didpush;
......@@ -391,7 +393,7 @@ RewriterVar Rewriter::pop(int argnum) {
#ifndef NDEBUG
versions[argnum] = version;
#endif
//printf("popping %d to %d\n", version, argnum);
// printf("popping %d to %d\n", version, argnum);
assembler->pop(fromArgnum(argnum));
return RewriterVar(this, argnum, version);
......@@ -403,7 +405,7 @@ void Rewriter::addDecision(int way) {
decision_path = (decision_path << 1) | way;
}
void Rewriter::addDependenceOn(ICInvalidator &invalidator) {
void Rewriter::addDependenceOn(ICInvalidator& invalidator) {
rewrite->addDependenceOn(invalidator);
}
......@@ -426,5 +428,4 @@ void Rewriter::finishAssembly(int continue_offset) {
assembler->pop(RAX);
}
}
}
......@@ -36,103 +36,103 @@ class Assembler;
// and a release one, instead of trying to make one class do both?
class RewriterVar {
private:
Rewriter *rewriter;
int argnum;
int version;
private:
Rewriter* rewriter;
int argnum;
int version;
public:
RewriterVar() : rewriter(NULL), argnum(-100), version(-100) {}
RewriterVar(Rewriter *rewriter, int argnum, int version);
RewriterVar& operator=(const RewriterVar &rhs);
public:
RewriterVar() : rewriter(NULL), argnum(-100), version(-100) {}
RewriterVar(Rewriter* rewriter, int argnum, int version);
RewriterVar& operator=(const RewriterVar& rhs);
#ifndef NDEBUG
void assertValid() const;
void lock();
void unlock();
void assertValid() const;
void lock();
void unlock();
#else
inline void assertValid() const {}
inline void lock() {}
inline void unlock() {}
inline void assertValid() const {}
inline void lock() {}
inline void unlock() {}
#endif
int getArgnum();
void addGuard(intptr_t val);
void addGuardNotEq(intptr_t val);
// More efficient than getAttr().addGuard(), but less efficient than addGuard() if the value is already available:
void addAttrGuard(int offset, intptr_t val);
RewriterVar getAttr(int offset, int dest);
void incAttr(int offset);
void setAttr(int offset, const RewriterVar &val, bool user_visible=true);
RewriterVar move(int argnum);
bool isInReg();
void push();
RewriterVar cmp(AST_TYPE::AST_TYPE cmp_type, const RewriterVar &val, int dest);
RewriterVar toBool(int dest);
friend class Rewriter;
int getArgnum();
void addGuard(intptr_t val);
void addGuardNotEq(intptr_t val);
// More efficient than getAttr().addGuard(), but less efficient than addGuard() if the value is already available:
void addAttrGuard(int offset, intptr_t val);
RewriterVar getAttr(int offset, int dest);
void incAttr(int offset);
void setAttr(int offset, const RewriterVar& val, bool user_visible = true);
RewriterVar move(int argnum);
bool isInReg();
void push();
RewriterVar cmp(AST_TYPE::AST_TYPE cmp_type, const RewriterVar& val, int dest);
RewriterVar toBool(int dest);
friend class Rewriter;
};
class Rewriter : public ICSlotRewrite::CommitHook {
private:
std::unique_ptr<ICSlotRewrite> rewrite;
assembler::Assembler *assembler;
const int num_orig_args;
const int num_temp_regs;
private:
std::unique_ptr<ICSlotRewrite> rewrite;
assembler::Assembler* assembler;
const int num_orig_args;
const int num_temp_regs;
void finishAssembly(int continue_offset);
void finishAssembly(int continue_offset);
int alloca_bytes;
int max_pushes;
std::vector<int> pushes;
int alloca_bytes;
int max_pushes;
std::vector<int> pushes;
#ifndef NDEBUG
std::unordered_map<int, int> versions;
int next_version;
bool changed_something;
std::unordered_set<int> locked;
std::unordered_map<int, int> versions;
int next_version;
bool changed_something;
std::unordered_set<int> locked;
#endif
int ndecisions;
uint64_t decision_path;
int ndecisions;
uint64_t decision_path;
Rewriter(ICSlotRewrite* rewrite, int num_orig_args, int num_temp_regs);
Rewriter(ICSlotRewrite* rewrite, int num_orig_args, int num_temp_regs);
void addPush(int version);
public:
static Rewriter* createRewriter(void* ic_rtn_addr, int num_orig_args, int num_temp_regs, const char* debug_name);
void addPush(int version);
public:
static Rewriter* createRewriter(void* ic_rtn_addr, int num_orig_args, int num_temp_regs, const char* debug_name);
#ifndef NDEBUG
int mutate(int argnum);
void lock(int argnum);
void unlock(int argnum);
void checkVersion(int argnum, int version);
void checkArgsValid();
int mutate(int argnum);
void lock(int argnum);
void unlock(int argnum);
void checkVersion(int argnum, int version);
void checkArgsValid();
#else
inline int mutate(int argnum) { return 0; }
inline void lock(int argnum) {}
inline void unlock(int argnum) {}
inline void checkVersion(int argnum, int version) {}
inline void checkArgsValid() {}
inline int mutate(int argnum) { return 0; }
inline void lock(int argnum) {}
inline void unlock(int argnum) {}
inline void checkVersion(int argnum, int version) {}
inline void checkArgsValid() {}
#endif
void addDecision(int way);
void addDecision(int way);
RewriterVar alloca_(int bytes, int dest_argnum);
RewriterVar getArg(int argnum);
RewriterVar alloca_(int bytes, int dest_argnum);
RewriterVar getArg(int argnum);
void trap();
void nop();
void annotate(int num);
RewriterVar pop(int argnum);
RewriterVar call(void* func_addr);
RewriterVar loadConst(int argnum, intptr_t val);
void trap();
void nop();
void annotate(int num);
RewriterVar pop(int argnum);
RewriterVar call(void* func_addr);
RewriterVar loadConst(int argnum, intptr_t val);
void addDependenceOn(ICInvalidator&);
void commit();
void addDependenceOn(ICInvalidator&);
void commit();
friend class RewriterVar;
friend class RewriterVar;
};
}
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -36,13 +36,9 @@ struct Register {
bool isCalleeSave();
bool operator==(const Register &rhs) const {
return regnum == rhs.regnum;
}
bool operator==(const Register& rhs) const { return regnum == rhs.regnum; }
bool operator!=(const Register &rhs) const {
return !(*this == rhs);
}
bool operator!=(const Register& rhs) const { return !(*this == rhs); }
void dump() const;
};
......@@ -69,11 +65,11 @@ inline bool Register::isCalleeSave() {
}
struct Indirect {
public:
const Register base;
const int offset;
public:
const Register base;
const int offset;
Indirect(const Register base, int offset) : base(base), offset(offset) {}
Indirect(const Register base, int offset) : base(base), offset(offset) {}
};
struct XMMRegister {
......@@ -81,13 +77,9 @@ struct XMMRegister {
explicit constexpr XMMRegister(int regnum) : regnum(regnum) {}
bool operator==(const XMMRegister &rhs) const {
return regnum == rhs.regnum;
}
bool operator==(const XMMRegister& rhs) const { return regnum == rhs.regnum; }
bool operator!=(const XMMRegister &rhs) const {
return !(*this == rhs);
}
bool operator!=(const XMMRegister& rhs) const { return !(*this == rhs); }
};
const XMMRegister XMM0(0);
......@@ -157,7 +149,6 @@ struct JumpDestination {
constexpr JumpDestination(OffsetType type, int offset) : type(type), offset(offset) {}
static JumpDestination fromStart(int offset) { return JumpDestination(FROM_START, offset); }
};
}
}
......
......@@ -28,7 +28,8 @@
namespace pyston {
void FunctionAddressRegistry::registerFunction(const std::string& name, void* addr, int length, llvm::Function* llvm_func) {
void FunctionAddressRegistry::registerFunction(const std::string& name, void* addr, int length,
llvm::Function* llvm_func) {
assert(addr);
assert(functions.count(addr) == 0);
functions.insert(std::make_pair(addr, FuncInfo(name, length, llvm_func)));
......@@ -42,19 +43,19 @@ void FunctionAddressRegistry::dumpPerfMap() {
code = llvm::sys::fs::create_directory(out_path, false);
assert(!code);
FILE *index_f = fopen((out_path + "/index.txt").c_str(), "w");
FILE* index_f = fopen((out_path + "/index.txt").c_str(), "w");
char buf[80];
snprintf(buf, 80, "/tmp/perf-%d.map", getpid());
FILE *f = fopen(buf, "w");
for (const auto &p : functions) {
FILE* f = fopen(buf, "w");
for (const auto& p : functions) {
const FuncInfo& info = p.second;
fprintf(f, "%lx %x %s\n", (uintptr_t)p.first, info.length, info.name.c_str());
if (info.length > 0) {
fprintf(index_f, "%lx %s\n", (uintptr_t)p.first, info.name.c_str());
FILE *data_f = fopen((out_path + "/" + info.name).c_str(), "wb");
FILE* data_f = fopen((out_path + "/" + info.name).c_str(), "wb");
int written = fwrite((void*)p.first, 1, info.length, data_f);
assert(written == info.length);
......@@ -77,7 +78,7 @@ llvm::Function* FunctionAddressRegistry::getLLVMFuncAtAddress(void* addr) {
return NULL;
}
llvm::Function *r = g.stdlib_module->getFunction(name);
llvm::Function* r = g.stdlib_module->getFunction(name);
if (!r) {
lookup_neg_cache.insert(addr);
......@@ -101,7 +102,7 @@ static std::string tryDemangle(const char* s) {
return rtn;
}
std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool demangle, bool *out_success) {
std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool demangle, bool* out_success) {
FuncMap::iterator it = functions.find(addr);
if (it == functions.end()) {
Dl_info info;
......@@ -110,8 +111,9 @@ std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool deman
if (success && info.dli_sname == NULL)
success = false;
if (out_success) *out_success = success;
//if (success && info.dli_saddr == addr) {
if (out_success)
*out_success = success;
// if (success && info.dli_saddr == addr) {
if (success) {
if (demangle)
return tryDemangle(info.dli_sname);
......@@ -121,7 +123,8 @@ std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool deman
return "<unknown>";
}
if (out_success) *out_success = true;
if (out_success)
*out_success = true;
if (!demangle)
return it->second.name;
......@@ -129,53 +132,51 @@ std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool deman
}
class RegistryEventListener : public llvm::JITEventListener {
public:
void NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
static StatCounter code_bytes("code_bytes");
code_bytes.log(Obj.getData().size());
public:
void NotifyObjectEmitted(const llvm::ObjectImage& Obj) {
static StatCounter code_bytes("code_bytes");
code_bytes.log(Obj.getData().size());
llvm::error_code code;
for (llvm::object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E;
llvm::error_code code;
for (llvm::object::symbol_iterator I = Obj.begin_symbols(), E = Obj.end_symbols(); I != E;
#if LLVMREV < 200442
I = I.increment(code)
I = I.increment(code)
#else
++I
++I
#endif
) {
llvm::object::section_iterator section(Obj.end_sections());
code = I->getSection(section);
assert(!code);
bool is_text;
code = section->isText(is_text);
assert(!code);
if (!is_text)
continue;
llvm::StringRef name;
uint64_t addr, size, offset;
code = I->getName(name);
assert(!code);
code = I->getAddress(addr);
assert(!code);
code = I->getSize(size);
assert(!code);
code = I->getFileOffset(offset);
assert(!code);
if (name == ".text")
continue;
//printf("%lx %lx %lx %s\n", addr, addr + size, offset, name.data());
g.func_addr_registry.registerFunction(name.data(), (void*)addr, size, NULL);
}
) {
llvm::object::section_iterator section(Obj.end_sections());
code = I->getSection(section);
assert(!code);
bool is_text;
code = section->isText(is_text);
assert(!code);
if (!is_text)
continue;
llvm::StringRef name;
uint64_t addr, size, offset;
code = I->getName(name);
assert(!code);
code = I->getAddress(addr);
assert(!code);
code = I->getSize(size);
assert(!code);
code = I->getFileOffset(offset);
assert(!code);
if (name == ".text")
continue;
// printf("%lx %lx %lx %s\n", addr, addr + size, offset, name.data());
g.func_addr_registry.registerFunction(name.data(), (void*)addr, size, NULL);
}
}
};
GlobalState::GlobalState() : context(llvm::getGlobalContext()) {
};
GlobalState::GlobalState() : context(llvm::getGlobalContext()) {};
llvm::JITEventListener* makeRegistryListener() {
return new RegistryEventListener();
}
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -25,8 +25,6 @@ void initCodegen();
void teardownCodegen();
void printAllIR();
int joinRuntime();
}
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
......@@ -23,8 +23,7 @@ extern "C" char* reoptCompiledFunc(CompiledFunction*);
class AST_Module;
class BoxedModule;
void compileAndRunModule(AST_Module *m, BoxedModule *bm);
void compileAndRunModule(AST_Module* m, BoxedModule* bm);
}
#endif
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment