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,9 +22,8 @@ ...@@ -22,9 +22,8 @@
namespace pyston { namespace pyston {
template <typename T> template <typename T> class BBAnalyzer {
class BBAnalyzer { public:
public:
typedef std::unordered_map<std::string, T> Map; typedef std::unordered_map<std::string, T> Map;
typedef std::unordered_map<CFGBlock*, Map> AllMap; typedef std::unordered_map<CFGBlock*, Map> AllMap;
...@@ -32,11 +31,11 @@ class BBAnalyzer { ...@@ -32,11 +31,11 @@ class BBAnalyzer {
virtual T merge(T from, T into) const = 0; virtual T merge(T from, T into) const = 0;
virtual T mergeBlank(T into) const = 0; virtual T mergeBlank(T into) const = 0;
virtual void processBB(Map &starting, CFGBlock *block) const = 0; virtual void processBB(Map& starting, CFGBlock* block) const = 0;
}; };
template <typename T> 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); assert(!reverse);
typedef typename BBAnalyzer<T>::Map Map; typedef typename BBAnalyzer<T>::Map Map;
...@@ -49,17 +48,18 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> & ...@@ -49,17 +48,18 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &
q.push_back(cfg->getStartingBlock()); q.push_back(cfg->getStartingBlock());
while (q.size()) { while (q.size()) {
CFGBlock *block = q.back(); CFGBlock* block = q.back();
q.pop_back(); q.pop_back();
Map initial = states[block]; 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); Map ending = Map(initial);
analyzer.processBB(ending, block); analyzer.processBB(ending, block);
for (int i = 0; i < block->successors.size(); i++) { 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 changed = false;
bool initial = false; bool initial = false;
if (states.count(next_block) == 0) { if (states.count(next_block) == 0) {
...@@ -67,8 +67,8 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> & ...@@ -67,8 +67,8 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &
initial = true; initial = true;
} }
Map &next = states[next_block]; Map& next = states[next_block];
for (const auto &p : ending) { for (const auto& p : ending) {
if (next.count(p.first) == 0) { if (next.count(p.first) == 0) {
changed = true; changed = true;
if (initial) { if (initial) {
...@@ -77,7 +77,7 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> & ...@@ -77,7 +77,7 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &
next[p.first] = analyzer.mergeBlank(p.second); next[p.first] = analyzer.mergeBlank(p.second);
} }
} else { } else {
T &next_elt = next[p.first]; T& next_elt = next[p.first];
T new_elt = analyzer.merge(p.second, next_elt); T new_elt = analyzer.merge(p.second, next_elt);
if (next_elt != new_elt) { if (next_elt != new_elt) {
...@@ -87,7 +87,7 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> & ...@@ -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)) if (ending.count(p.first))
continue; continue;
...@@ -108,7 +108,6 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> & ...@@ -108,7 +108,6 @@ typename BBAnalyzer<T>::AllMap computeFixedPoint(CFG* cfg, const BBAnalyzer<T> &
return states; return states;
} }
} }
#endif #endif
This diff is collapsed.
...@@ -27,11 +27,11 @@ class CFGBlock; ...@@ -27,11 +27,11 @@ class CFGBlock;
class ScopeInfo; class ScopeInfo;
class LivenessAnalysis { class LivenessAnalysis {
public: public:
bool isLiveAtEnd(const std::string &name, CFGBlock *block); bool isLiveAtEnd(const std::string& name, CFGBlock* block);
}; };
class DefinednessAnalysis { class DefinednessAnalysis {
public: public:
enum DefinitionLevel { enum DefinitionLevel {
Undefined, Undefined,
PotentiallyDefined, PotentiallyDefined,
...@@ -39,40 +39,38 @@ class DefinednessAnalysis { ...@@ -39,40 +39,38 @@ class DefinednessAnalysis {
}; };
typedef std::unordered_set<std::string> RequiredSet; typedef std::unordered_set<std::string> RequiredSet;
private: private:
std::unordered_map<CFGBlock*, std::unordered_map<std::string, DefinitionLevel> > results; std::unordered_map<CFGBlock*, std::unordered_map<std::string, DefinitionLevel> > results;
std::unordered_map<CFGBlock*, const RequiredSet> defined; std::unordered_map<CFGBlock*, const RequiredSet> defined;
ScopeInfo *scope_info; ScopeInfo* scope_info;
public: public:
DefinednessAnalysis(AST_arguments *args, CFG* cfg, ScopeInfo *scope_info); DefinednessAnalysis(AST_arguments* args, CFG* cfg, ScopeInfo* scope_info);
DefinitionLevel isDefinedAt(const std::string &name, CFGBlock *block); DefinitionLevel isDefinedAt(const std::string& name, CFGBlock* block);
const RequiredSet& getDefinedNamesAt(CFGBlock *block); const RequiredSet& getDefinedNamesAt(CFGBlock* block);
}; };
class PhiAnalysis { class PhiAnalysis {
public: public:
typedef std::unordered_set<std::string> RequiredSet; typedef std::unordered_set<std::string> RequiredSet;
private: private:
DefinednessAnalysis definedness; DefinednessAnalysis definedness;
LivenessAnalysis *liveness; LivenessAnalysis* liveness;
std::unordered_map<CFGBlock*, const RequiredSet> required_phis; std::unordered_map<CFGBlock*, const RequiredSet> required_phis;
public: public:
PhiAnalysis(AST_arguments*, CFG* cfg, LivenessAnalysis *liveness, ScopeInfo *scope_info); PhiAnalysis(AST_arguments*, CFG* cfg, LivenessAnalysis* liveness, ScopeInfo* scope_info);
bool isRequired(const std::string &name, CFGBlock* block); bool isRequired(const std::string& name, CFGBlock* block);
bool isRequiredAfter(const std::string &name, CFGBlock* block); bool isRequiredAfter(const std::string& name, CFGBlock* block);
const RequiredSet& getAllRequiredAfter(CFGBlock *block); const RequiredSet& getAllRequiredAfter(CFGBlock* block);
const RequiredSet& getAllDefinedAt(CFGBlock *block); const RequiredSet& getAllDefinedAt(CFGBlock* block);
bool isPotentiallyUndefinedAfter(const std::string &name, CFGBlock* block); bool isPotentiallyUndefinedAfter(const std::string& name, CFGBlock* block);
}; };
LivenessAnalysis* computeLivenessInfo(CFG*); LivenessAnalysis* computeLivenessInfo(CFG*);
PhiAnalysis* computeRequiredPhis(AST_arguments*, CFG*, LivenessAnalysis*, ScopeInfo* scope_Info); PhiAnalysis* computeRequiredPhis(AST_arguments*, CFG*, LivenessAnalysis*, ScopeInfo* scope_Info);
} }
#endif #endif
This diff is collapsed.
...@@ -23,38 +23,36 @@ class AST; ...@@ -23,38 +23,36 @@ class AST;
class AST_Module; class AST_Module;
class ScopeInfo { class ScopeInfo {
public: public:
virtual ~ScopeInfo() {} virtual ~ScopeInfo() {}
virtual ScopeInfo* getParent() = 0; virtual ScopeInfo* getParent() = 0;
virtual bool createsClosure() = 0; virtual bool createsClosure() = 0;
virtual bool takesClosure() = 0; virtual bool takesClosure() = 0;
virtual bool refersToGlobal(const std::string &name) = 0; virtual bool refersToGlobal(const std::string& name) = 0;
virtual bool refersToClosure(const std::string name) = 0; virtual bool refersToClosure(const std::string name) = 0;
virtual bool saveInClosure(const std::string name) = 0; virtual bool saveInClosure(const std::string name) = 0;
}; };
class ScopingAnalysis { class ScopingAnalysis {
public: public:
struct ScopeNameUsage; struct ScopeNameUsage;
typedef std::unordered_map<AST*, ScopeNameUsage*> NameUsageMap; typedef std::unordered_map<AST*, ScopeNameUsage*> NameUsageMap;
private: private:
std::unordered_map<AST*, ScopeInfo*> scopes; std::unordered_map<AST*, ScopeInfo*> scopes;
AST_Module* parent_module; AST_Module* parent_module;
ScopeInfo* analyzeSubtree(AST* node); ScopeInfo* analyzeSubtree(AST* node);
void processNameUsages(NameUsageMap* usages); void processNameUsages(NameUsageMap* usages);
public: public:
ScopingAnalysis(AST_Module *m); ScopingAnalysis(AST_Module* m);
ScopeInfo* getScopeInfoForNode(AST* node); ScopeInfo* getScopeInfoForNode(AST* node);
}; };
ScopingAnalysis* runScopingAnalysis(AST_Module* m); ScopingAnalysis* runScopingAnalysis(AST_Module* m);
} }
#endif #endif
This diff is collapsed.
...@@ -26,7 +26,7 @@ namespace pyston { ...@@ -26,7 +26,7 @@ namespace pyston {
class ScopeInfo; class ScopeInfo;
class TypeAnalysis { class TypeAnalysis {
public: public:
enum SpeculationLevel { enum SpeculationLevel {
NONE, NONE,
SOME, SOME,
...@@ -34,14 +34,15 @@ class TypeAnalysis { ...@@ -34,14 +34,15 @@ class TypeAnalysis {
virtual ~TypeAnalysis() {} virtual ~TypeAnalysis() {}
virtual ConcreteCompilerType* getTypeAtBlockStart(const std::string &name, CFGBlock* block) = 0; virtual ConcreteCompilerType* getTypeAtBlockStart(const std::string& name, CFGBlock* block) = 0;
virtual ConcreteCompilerType* getTypeAtBlockEnd(const std::string &name, CFGBlock* block) = 0; virtual ConcreteCompilerType* getTypeAtBlockEnd(const std::string& name, CFGBlock* block) = 0;
virtual BoxedClass* speculatedExprClass(AST_expr*) = 0; virtual BoxedClass* speculatedExprClass(AST_expr*) = 0;
}; };
//TypeAnalysis* analyze(CFG *cfg, std::unordered_map<std::string, ConcreteCompilerType*> arg_types); // 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* doTypeAnalysis(CFG* cfg, const std::vector<AST_expr*>& arg_names,
const std::vector<ConcreteCompilerType*>& arg_types,
TypeAnalysis::SpeculationLevel speculation, ScopeInfo* scope_info);
} }
#endif #endif
...@@ -22,22 +22,7 @@ namespace pyston { ...@@ -22,22 +22,7 @@ namespace pyston {
namespace assembler { namespace assembler {
const char* regnames[] = { const char* regnames[] = {
"rax", "rax", "rcx", "rdx", "rbx", "rsp", "rbp", "rsi", "rdi", "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
"rcx",
"rdx",
"rbx",
"rsp",
"rbp",
"rsi",
"rdi",
"r8",
"r9",
"r10",
"r11",
"r12",
"r13",
"r14",
"r15",
}; };
void Register::dump() const { void Register::dump() const {
...@@ -85,7 +70,7 @@ GenericRegister GenericRegister::fromDwarf(int dwarf_regnum) { ...@@ -85,7 +70,7 @@ GenericRegister GenericRegister::fromDwarf(int dwarf_regnum) {
void Assembler::emitArith(Immediate imm, Register r, int opcode) { 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; int64_t amount = imm.val;
RELEASE_ASSERT(-0x80 <= amount && amount < 0x80 && "unsupported", ""); RELEASE_ASSERT(-0x80 <= amount && amount < 0x80 && "unsupported", "");
...@@ -142,7 +127,6 @@ void Assembler::emitSIB(uint8_t scalebits, uint8_t index, uint8_t base) { ...@@ -142,7 +127,6 @@ void Assembler::emitSIB(uint8_t scalebits, uint8_t index, uint8_t base) {
void Assembler::mov(Immediate val, Register dest) { void Assembler::mov(Immediate val, Register dest) {
int rex = REX_W; int rex = REX_W;
...@@ -159,7 +143,7 @@ void Assembler::mov(Immediate val, Register dest) { ...@@ -159,7 +143,7 @@ void Assembler::mov(Immediate val, Register dest) {
void Assembler::movq(Immediate src, Indirect dest) { void Assembler::movq(Immediate src, Indirect dest) {
int64_t src_val = src.val; 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; int rex = REX_W;
...@@ -418,7 +402,7 @@ void Assembler::movsd(Indirect src, XMMRegister dest) { ...@@ -418,7 +402,7 @@ void Assembler::movsd(Indirect src, XMMRegister dest) {
void Assembler::push(Register reg) { 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 assert(reg != RSP); // this might work but most likely a bug
...@@ -433,7 +417,7 @@ void Assembler::push(Register reg) { ...@@ -433,7 +417,7 @@ void Assembler::push(Register reg) {
} }
void Assembler::pop(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 assert(reg != RSP); // this might work but most likely a bug
...@@ -467,7 +451,6 @@ void Assembler::inc(Indirect mem) { ...@@ -467,7 +451,6 @@ void Assembler::inc(Indirect mem) {
void Assembler::callq(Register r) { void Assembler::callq(Register r) {
assert(r == R11 && "untested"); assert(r == R11 && "untested");
...@@ -503,7 +486,7 @@ void Assembler::cmp(Register reg1, Register reg2) { ...@@ -503,7 +486,7 @@ void Assembler::cmp(Register reg1, Register reg2) {
void Assembler::cmp(Register reg, Immediate imm) { void Assembler::cmp(Register reg, Immediate imm) {
int64_t val = imm.val; 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; int reg_idx = reg.regnum;
...@@ -522,7 +505,7 @@ void Assembler::cmp(Register reg, Immediate imm) { ...@@ -522,7 +505,7 @@ void Assembler::cmp(Register reg, Immediate imm) {
void Assembler::cmp(Indirect mem, Immediate imm) { void Assembler::cmp(Indirect mem, Immediate imm) {
int64_t val = imm.val; 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; int src_idx = mem.base.regnum;
...@@ -607,7 +590,8 @@ void Assembler::jmp_cond(JumpDestination dest, ConditionCode condition) { ...@@ -607,7 +590,8 @@ void Assembler::jmp_cond(JumpDestination dest, ConditionCode condition) {
assert(dest.type == JumpDestination::FROM_START); assert(dest.type == JumpDestination::FROM_START);
int offset = dest.offset - (addr - start_addr) - 2; int offset = dest.offset - (addr - start_addr) - 2;
if (unlikely) offset--; if (unlikely)
offset--;
if (offset >= -0x80 && offset < 0x80) { if (offset >= -0x80 && offset < 0x80) {
if (unlikely) if (unlikely)
...@@ -681,11 +665,11 @@ uint8_t* Assembler::emitCall(void* ptr, Register scratch) { ...@@ -681,11 +665,11 @@ uint8_t* Assembler::emitCall(void* ptr, Register scratch) {
return addr; 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); assert(stack_info.has_scratch);
int offset = 0; int offset = 0;
for (const GenericRegister &r : to_push) { for (const GenericRegister& r : to_push) {
assert(stack_info.scratch_bytes >= offset + 8); assert(stack_info.scratch_bytes >= offset + 8);
Indirect next_slot(RBP, offset + stack_info.scratch_rbp_offset); Indirect next_slot(RBP, offset + stack_info.scratch_rbp_offset);
...@@ -704,11 +688,11 @@ void Assembler::emitBatchPush(StackInfo stack_info, const std::vector<GenericReg ...@@ -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); assert(stack_info.has_scratch);
int offset = 0; int offset = 0;
for (const GenericRegister &r : to_push) { for (const GenericRegister& r : to_push) {
assert(stack_info.scratch_bytes >= offset + 8); assert(stack_info.scratch_bytes >= offset + 8);
Indirect next_slot(RBP, offset + stack_info.scratch_rbp_offset); Indirect next_slot(RBP, offset + stack_info.scratch_rbp_offset);
...@@ -747,16 +731,17 @@ void Assembler::emitAnnotation(int num) { ...@@ -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); assert(start_addr < slowpath_start);
static const int INITIAL_CALL_SIZE = 13; static const int INITIAL_CALL_SIZE = 13;
assert(end_addr > slowpath_start + INITIAL_CALL_SIZE); assert(end_addr > slowpath_start + INITIAL_CALL_SIZE);
#ifndef NDEBUG #ifndef NDEBUG
//if (VERBOSITY()) printf("initializing patchpoint at %p - %p\n", addr, addr + size); // if (VERBOSITY()) printf("initializing patchpoint at %p - %p\n", addr, addr + size);
//for (int i = 0; i < size; i++) { // for (int i = 0; i < size; i++) {
//printf("%02x ", *(addr + i)); // printf("%02x ", *(addr + i));
//} //}
//printf("\n"); // printf("\n");
// Check the exact form of the patchpoint call. // Check the exact form of the patchpoint call.
// It's important to make sure that the only live registers // 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 ...@@ -800,8 +785,8 @@ uint8_t* initializePatchpoint2(uint8_t* start_addr, uint8_t* slowpath_start, uin
Assembler assem(slowpath_start, end_addr - slowpath_start); Assembler assem(slowpath_start, end_addr - slowpath_start);
//if (regs_to_spill.size()) // if (regs_to_spill.size())
//assem.trap(); // assem.trap();
assem.emitBatchPush(stack_info, regs_to_spill); assem.emitBatchPush(stack_info, regs_to_spill);
uint8_t* rtn = assem.emitCall(call_addr, R11); uint8_t* rtn = assem.emitCall(call_addr, R11);
assem.emitBatchPop(stack_info, regs_to_spill); assem.emitBatchPop(stack_info, regs_to_spill);
...@@ -809,6 +794,5 @@ uint8_t* initializePatchpoint2(uint8_t* start_addr, uint8_t* slowpath_start, uin ...@@ -809,6 +794,5 @@ uint8_t* initializePatchpoint2(uint8_t* start_addr, uint8_t* slowpath_start, uin
return rtn; return rtn;
} }
} }
} }
...@@ -49,13 +49,14 @@ enum ConditionCode { ...@@ -49,13 +49,14 @@ enum ConditionCode {
}; };
class Assembler { class Assembler {
private: private:
uint8_t *const start_addr, *const end_addr; uint8_t* const start_addr, *const end_addr;
uint8_t *addr; uint8_t* addr;
static const uint8_t OPCODE_ADD = 0b000, OPCODE_SUB = 0b101; 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; static const uint8_t REX_B = 1, REX_X = 2, REX_R = 4, REX_W = 8;
private:
private:
void emitByte(uint8_t b); void emitByte(uint8_t b);
void emitInt(int64_t n, int bytes); void emitInt(int64_t n, int bytes);
void emitRex(uint8_t rex); void emitRex(uint8_t rex);
...@@ -63,7 +64,7 @@ class Assembler { ...@@ -63,7 +64,7 @@ class Assembler {
void emitSIB(uint8_t scalebits, uint8_t index, uint8_t base); void emitSIB(uint8_t scalebits, uint8_t index, uint8_t base);
void emitArith(Immediate imm, Register reg, int opcode); void emitArith(Immediate imm, Register reg, int opcode);
public: public:
Assembler(uint8_t* start, int size) : start_addr(start), end_addr(start + size), addr(start_addr) {} Assembler(uint8_t* start, int size) : start_addr(start), end_addr(start + size), addr(start_addr) {}
void nop() { emitByte(0x90); } void nop() { emitByte(0x90); }
...@@ -112,8 +113,8 @@ class Assembler { ...@@ -112,8 +113,8 @@ class Assembler {
// Macros: // Macros:
uint8_t* emitCall(void* func_addr, Register scratch); uint8_t* emitCall(void* func_addr, Register scratch);
void emitBatchPop(StackInfo stack_info, const std::vector<GenericRegister> &to_push); void emitBatchPop(StackInfo stack_info, const std::vector<GenericRegister>& to_push);
void emitBatchPush(StackInfo stack_info, const std::vector<GenericRegister> &to_push); void emitBatchPush(StackInfo stack_info, const std::vector<GenericRegister>& to_push);
void fillWithNops(); void fillWithNops();
void fillWithNopsExcept(int bytes); void fillWithNopsExcept(int bytes);
void emitAnnotation(int num); void emitAnnotation(int num);
...@@ -121,8 +122,8 @@ class Assembler { ...@@ -121,8 +122,8 @@ class Assembler {
bool isExactlyFull() { return addr == end_addr; } 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 ...@@ -59,7 +59,8 @@ ICSlotRewrite::ICSlotRewrite(ICInfo* ic, const char* debug_name) : ic(ic), debug
assembler = new Assembler(buf, ic->getSlotSize()); assembler = new Assembler(buf, ic->getSlotSize());
assembler->nop(); assembler->nop();
if (VERBOSITY()) printf("starting %s icentry\n", debug_name); if (VERBOSITY())
printf("starting %s icentry\n", debug_name);
} }
ICSlotRewrite::~ICSlotRewrite() { ICSlotRewrite::~ICSlotRewrite() {
...@@ -67,27 +68,28 @@ ICSlotRewrite::~ICSlotRewrite() { ...@@ -67,27 +68,28 @@ ICSlotRewrite::~ICSlotRewrite() {
free(buf); free(buf);
} }
void ICSlotRewrite::commit(uint64_t decision_path, CommitHook *hook) { void ICSlotRewrite::commit(uint64_t decision_path, CommitHook* hook) {
bool still_valid = true; bool still_valid = true;
for (int i = 0; i < dependencies.size(); i++) { for (int i = 0; i < dependencies.size(); i++) {
int orig_version = dependencies[i].second; int orig_version = dependencies[i].second;
ICInvalidator *invalidator = dependencies[i].first; ICInvalidator* invalidator = dependencies[i].first;
if (orig_version != invalidator->version()) { if (orig_version != invalidator->version()) {
still_valid = false; still_valid = false;
break; break;
} }
} }
if (!still_valid) { 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; return;
} }
ICSlotInfo *ic_entry = ic->pickEntryForRewrite(decision_path, debug_name); ICSlotInfo* ic_entry = ic->pickEntryForRewrite(decision_path, debug_name);
if (ic_entry == NULL) if (ic_entry == NULL)
return; return;
for (int i = 0; i < dependencies.size(); i++) { for (int i = 0; i < dependencies.size(); i++) {
ICInvalidator *invalidator = dependencies[i].first; ICInvalidator* invalidator = dependencies[i].first;
invalidator->addDependent(ic_entry); invalidator->addDependent(ic_entry);
} }
...@@ -98,13 +100,13 @@ void ICSlotRewrite::commit(uint64_t decision_path, CommitHook *hook) { ...@@ -98,13 +100,13 @@ void ICSlotRewrite::commit(uint64_t decision_path, CommitHook *hook) {
assert(assembler->isExactlyFull()); 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()); memcpy(slot_start, buf, ic->getSlotSize());
llvm::sys::Memory::InvalidateInstructionCache(slot_start, 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())); dependencies.push_back(std::make_pair(&invalidator, invalidator.version()));
} }
...@@ -144,7 +146,7 @@ ICSlotRewrite* ICInfo::startRewrite(const char* debug_name) { ...@@ -144,7 +146,7 @@ ICSlotRewrite* ICInfo::startRewrite(const char* debug_name) {
ICSlotInfo* ICInfo::pickEntryForRewrite(uint64_t decision_path, const char* debug_name) { ICSlotInfo* ICInfo::pickEntryForRewrite(uint64_t decision_path, const char* debug_name) {
for (int i = 0; i < getNumSlots(); i++) { for (int i = 0; i < getNumSlots(); i++) {
SlotInfo &sinfo = slots[i]; SlotInfo& sinfo = slots[i];
if (!sinfo.is_patched) { if (!sinfo.is_patched) {
if (VERBOSITY()) { if (VERBOSITY()) {
printf("committing %s icentry to unused slot %d at %p\n", debug_name, i, start_addr); 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 ...@@ -160,7 +162,7 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(uint64_t decision_path, const char* debu
for (int _i = 0; _i < num_slots; _i++) { for (int _i = 0; _i < num_slots; _i++) {
int i = (_i + next_slot_to_try) % num_slots; 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) { if (sinfo.is_patched && sinfo.decision_path != decision_path) {
continue; continue;
} }
...@@ -174,20 +176,27 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(uint64_t decision_path, const char* debu ...@@ -174,20 +176,27 @@ ICSlotInfo* ICInfo::pickEntryForRewrite(uint64_t decision_path, const char* debu
sinfo.decision_path = decision_path; sinfo.decision_path = decision_path;
return &sinfo.entry; 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; 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++) { for (int i = 0; i < num_slots; i++) {
slots.push_back(SlotInfo(this, i)); slots.push_back(SlotInfo(this, i));
} }
} }
static std::unordered_map<void*, ICInfo*> ics_by_return_addr; 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(); int size = pp->totalSize();
uint8_t* end_addr = start_addr + size; uint8_t* end_addr = start_addr + size;
uint8_t* slowpath_addr = end_addr; uint8_t* slowpath_addr = end_addr;
...@@ -195,7 +204,8 @@ void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo* pp, St ...@@ -195,7 +204,8 @@ void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo* pp, St
uint8_t* rtn_addr; uint8_t* rtn_addr;
assembler::GenericRegister return_register; 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()) { if (pp->hasReturnValue()) {
static const int DWARF_RAX = 0; static const int DWARF_RAX = 0;
// It's possible that the return value doesn't get used, in which case // 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 ...@@ -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; 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); rtn_addr = initializePatchpoint2(start_addr, slowpath_start, (uint8_t*)end_addr, stack_info, live_outs);
} else { } else {
//for (int regnum : live_outs) { // for (int regnum : live_outs) {
//// LLVM has a bug where it incorrectly determines the set of liveouts; //// 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 //// so far it only seems to add additional ones to the set, which should
//// hopefully be safe. //// hopefully be safe.
//// Otherwise, I'd like to test here that it's only the registers //// Otherwise, I'd like to test here that it's only the registers
//// that we'd expect to be saved... //// 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); // ASSERT(regnum == 0 || regnum == 3 || regnum == 6 || regnum == 12 || regnum == 13 || regnum == 14 || regnum ==
// 15 || regnum == 7, "%d", regnum);
//} //}
initializePatchpoint(start_addr, size); initializePatchpoint(start_addr, size);
...@@ -231,17 +242,19 @@ void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo* pp, St ...@@ -231,17 +242,19 @@ void registerCompiledPatchpoint(uint8_t* start_addr, PatchpointSetupInfo* pp, St
// Not sure if this is worth it or not? // Not sure if this is worth it or not?
for (int i = 0; i < pp->num_slots; i++) { for (int i = 0; i < pp->num_slots; i++) {
uint8_t* start = start_addr + i * pp->slot_size; uint8_t* start = start_addr + i * pp->slot_size;
//std::unique_ptr<MCWriter> writer(createMCWriter(start, pp->slot_size * (pp->num_slots - i), 0)); // std::unique_ptr<MCWriter> writer(createMCWriter(start, pp->slot_size * (pp->num_slots - i), 0));
//writer->emitNop(); // writer->emitNop();
//writer->emitGuardFalse(); // writer->emitGuardFalse();
std::unique_ptr<Assembler> writer(new Assembler(start, pp->slot_size)); std::unique_ptr<Assembler> writer(new Assembler(start, pp->slot_size));
writer->nop(); writer->nop();
//writer->trap(); // writer->trap();
writer->jmp(JumpDestination::fromStart(pp->slot_size * (pp->num_slots - i))); 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) { ICInfo* getICInfo(void* rtn_addr) {
...@@ -256,17 +269,17 @@ void ICInfo::clear(ICSlotInfo* icentry) { ...@@ -256,17 +269,17 @@ void ICInfo::clear(ICSlotInfo* icentry) {
uint8_t* start = (uint8_t*)start_addr + icentry->idx * getSlotSize(); 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())); std::unique_ptr<Assembler> writer(new Assembler(start, getSlotSize()));
writer->nop(); writer->nop();
writer->jmp(JumpDestination::fromStart(getSlotSize())); writer->jmp(JumpDestination::fromStart(getSlotSize()));
//std::unique_ptr<MCWriter> writer(createMCWriter(start, getSlotSize(), 0)); // std::unique_ptr<MCWriter> writer(createMCWriter(start, getSlotSize(), 0));
//writer->emitNop(); // writer->emitNop();
//writer->emitGuardFalse(); // writer->emitGuardFalse();
//writer->endWithSlowpath(); // writer->endWithSlowpath();
llvm::sys::Memory::InvalidateInstructionCache(start, getSlotSize()); llvm::sys::Memory::InvalidateInstructionCache(start, getSlotSize());
} }
} }
...@@ -30,34 +30,35 @@ class ICInfo; ...@@ -30,34 +30,35 @@ class ICInfo;
class ICInvalidator; class ICInvalidator;
struct ICSlotInfo { struct ICSlotInfo {
public: public:
ICSlotInfo(ICInfo* ic, int idx) : ic(ic), idx(idx) {} ICSlotInfo(ICInfo* ic, int idx) : ic(ic), idx(idx) {}
ICInfo *ic; ICInfo* ic;
int idx; int idx;
void clear(); void clear();
}; };
class ICSlotRewrite { class ICSlotRewrite {
public: public:
class CommitHook { class CommitHook {
public: public:
virtual ~CommitHook() {} virtual ~CommitHook() {}
virtual void finishAssembly(int fastpath_offset) = 0; virtual void finishAssembly(int fastpath_offset) = 0;
}; };
private:
private:
ICInfo* ic; ICInfo* ic;
assembler::Assembler* assembler; assembler::Assembler* assembler;
const char* debug_name; const char* debug_name;
uint8_t *buf; uint8_t* buf;
std::vector<std::pair<ICInvalidator*, int64_t> > dependencies; std::vector<std::pair<ICInvalidator*, int64_t> > dependencies;
ICSlotRewrite(ICInfo* ic, const char* debug_name); ICSlotRewrite(ICInfo* ic, const char* debug_name);
public: public:
~ICSlotRewrite(); ~ICSlotRewrite();
assembler::Assembler* getAssembler() { return assembler; } assembler::Assembler* getAssembler() { return assembler; }
...@@ -71,13 +72,13 @@ class ICSlotRewrite { ...@@ -71,13 +72,13 @@ class ICSlotRewrite {
assembler::GenericRegister returnRegister(); assembler::GenericRegister returnRegister();
void addDependenceOn(ICInvalidator&); void addDependenceOn(ICInvalidator&);
void commit(uint64_t decision_path, CommitHook *hook); void commit(uint64_t decision_path, CommitHook* hook);
friend class ICInfo; friend class ICInfo;
}; };
class ICInfo { class ICInfo {
private: private:
struct SlotInfo { struct SlotInfo {
bool is_patched; bool is_patched;
uint64_t decision_path; uint64_t decision_path;
...@@ -98,16 +99,18 @@ class ICInfo { ...@@ -98,16 +99,18 @@ class ICInfo {
const llvm::CallingConv::ID calling_conv; const llvm::CallingConv::ID calling_conv;
const std::vector<int> live_outs; const std::vector<int> live_outs;
const assembler::GenericRegister return_register; const assembler::GenericRegister return_register;
TypeRecorder * const type_recorder; TypeRecorder* const type_recorder;
// for ICSlotRewrite: // for ICSlotRewrite:
ICSlotInfo *pickEntryForRewrite(uint64_t decision_path, const char* debug_name); ICSlotInfo* pickEntryForRewrite(uint64_t decision_path, const char* debug_name);
void* getSlowpathStart(); void* getSlowpathStart();
public: 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); ICInfo(void* start_addr, void* continue_addr, StackInfo stack_info, int num_slots, int slot_size,
void *const start_addr, *const continue_addr; 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 getSlotSize() { return slot_size; }
int getNumSlots() { return num_slots; } int getNumSlots() { return num_slots; }
...@@ -115,17 +118,16 @@ class ICInfo { ...@@ -115,17 +118,16 @@ class ICInfo {
const std::vector<int>& getLiveOuts() { return live_outs; } const std::vector<int>& getLiveOuts() { return live_outs; }
ICSlotRewrite* startRewrite(const char* debug_name); ICSlotRewrite* startRewrite(const char* debug_name);
void clear(ICSlotInfo *entry); void clear(ICSlotInfo* entry);
friend class ICSlotRewrite; friend class ICSlotRewrite;
}; };
class PatchpointSetupInfo; 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); ICInfo* getICInfo(void* rtn_addr);
} }
#endif #endif
This diff is collapsed.
...@@ -22,7 +22,7 @@ namespace pyston { ...@@ -22,7 +22,7 @@ namespace pyston {
class BoxedClass; class BoxedClass;
class MCWriter { class MCWriter {
public: public:
virtual ~MCWriter() {} virtual ~MCWriter() {}
virtual int numArgRegs() = 0; virtual int numArgRegs() = 0;
...@@ -50,12 +50,10 @@ class MCWriter { ...@@ -50,12 +50,10 @@ class MCWriter {
virtual void emitLoadConst(int reg, int64_t value) = 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 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; virtual void emitToBool(int argnum, int dest_argnum) = 0;
}; };
void initializePatchpoint(uint8_t* addr, int size); void initializePatchpoint(uint8_t* addr, int size);
MCWriter* createMCWriter(uint8_t* addr, int size, int num_temp_regs); MCWriter* createMCWriter(uint8_t* addr, int size, int num_temp_regs);
} }
#endif #endif
...@@ -50,11 +50,12 @@ Register fromArgnum(int argnum) { ...@@ -50,11 +50,12 @@ Register fromArgnum(int argnum) {
RELEASE_ASSERT(0, "%d", argnum); RELEASE_ASSERT(0, "%d", argnum);
} }
RewriterVar::RewriterVar(Rewriter *rewriter, int argnum, int version) : rewriter(rewriter), argnum(argnum), version(version) { RewriterVar::RewriterVar(Rewriter* rewriter, int argnum, int version)
//assert(rewriter.icentry.get()); : 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); assert(rewriter == NULL || rewriter == rhs.rewriter);
rhs.assertValid(); rhs.assertValid();
rewriter = rhs.rewriter; rewriter = rhs.rewriter;
...@@ -81,7 +82,7 @@ void RewriterVar::unlock() { ...@@ -81,7 +82,7 @@ void RewriterVar::unlock() {
#endif #endif
int RewriterVar::getArgnum() { int RewriterVar::getArgnum() {
//assert(rewriter); // assert(rewriter);
return argnum; return argnum;
} }
...@@ -128,7 +129,7 @@ RewriterVar RewriterVar::move(int dest_argnum) { ...@@ -128,7 +129,7 @@ RewriterVar RewriterVar::move(int dest_argnum) {
rewriter->assembler->mov(Indirect(RSP, offset), fromArgnum(dest_argnum)); rewriter->assembler->mov(Indirect(RSP, offset), fromArgnum(dest_argnum));
} else { } else {
int stack_size = rewriter->rewrite->getFuncStackSize(); 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); int offset = (this->argnum - 6) * 8 - (stack_size - 8);
rewriter->assembler->mov(Indirect(RBP, offset), fromArgnum(dest_argnum)); rewriter->assembler->mov(Indirect(RBP, offset), fromArgnum(dest_argnum));
} }
...@@ -151,7 +152,7 @@ void RewriterVar::addGuard(intptr_t val) { ...@@ -151,7 +152,7 @@ void RewriterVar::addGuard(intptr_t val) {
int bytes = 8 * rewriter->pushes.size() + rewriter->alloca_bytes; 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->push(RBP);
rewriter->assembler->mov(Immediate(val), RBP); rewriter->assembler->mov(Immediate(val), RBP);
rewriter->assembler->cmp(fromArgnum(this->argnum), RBP); rewriter->assembler->cmp(fromArgnum(this->argnum), RBP);
...@@ -159,7 +160,7 @@ void RewriterVar::addGuard(intptr_t val) { ...@@ -159,7 +160,7 @@ void RewriterVar::addGuard(intptr_t val) {
} else { } else {
rewriter->assembler->cmp(fromArgnum(this->argnum), Immediate(val)); 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) { void RewriterVar::addAttrGuard(int offset, intptr_t val) {
...@@ -170,7 +171,7 @@ 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; 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->push(RBP);
rewriter->assembler->mov(Immediate(val), RBP); rewriter->assembler->mov(Immediate(val), RBP);
rewriter->assembler->cmp(Indirect(fromArgnum(this->argnum), offset), RBP); rewriter->assembler->cmp(Indirect(fromArgnum(this->argnum), offset), RBP);
...@@ -178,7 +179,7 @@ void RewriterVar::addAttrGuard(int offset, intptr_t val) { ...@@ -178,7 +179,7 @@ void RewriterVar::addAttrGuard(int offset, intptr_t val) {
} else { } else {
rewriter->assembler->cmp(Indirect(fromArgnum(this->argnum), offset), Immediate(val)); 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) { void RewriterVar::addGuardNotEq(intptr_t val) {
...@@ -189,7 +190,7 @@ 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; int bytes = 8 * rewriter->pushes.size() + rewriter->alloca_bytes;
rewriter->assembler->cmp(fromArgnum(this->argnum), Immediate(val)); 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() { bool RewriterVar::isInReg() {
...@@ -205,7 +206,7 @@ void RewriterVar::push() { ...@@ -205,7 +206,7 @@ void RewriterVar::push() {
rewriter->addPush(this->version); 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(); assertValid();
rewriter->assembler->cmp(fromArgnum(this->argnum), fromArgnum(val.argnum)); 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 ...@@ -239,7 +240,7 @@ Rewriter* Rewriter::createRewriter(void* ic_rtn_addr, int num_orig_args, int num
static StatCounter rewriter_nopatch("rewriter_nopatch"); static StatCounter rewriter_nopatch("rewriter_nopatch");
ICInfo *ic = getICInfo(ic_rtn_addr); ICInfo* ic = getICInfo(ic_rtn_addr);
if (ic == NULL) { if (ic == NULL) {
rewriter_nopatch.log(); rewriter_nopatch.log();
return NULL; return NULL;
...@@ -249,21 +250,22 @@ Rewriter* Rewriter::createRewriter(void* ic_rtn_addr, int num_orig_args, int num ...@@ -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); 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) : Rewriter::Rewriter(ICSlotRewrite* rewrite, int num_orig_args, int num_temp_regs)
rewrite(rewrite), assembler(rewrite->getAssembler()), : rewrite(rewrite), assembler(rewrite->getAssembler()), num_orig_args(num_orig_args), num_temp_regs(num_temp_regs),
num_orig_args(num_orig_args), num_temp_regs(num_temp_regs), alloca_bytes(0), max_pushes(0) alloca_bytes(0), max_pushes(0)
#ifndef NDEBUG #ifndef NDEBUG
, next_version(2), changed_something(false) ,
next_version(2), changed_something(false)
#endif #endif
, ndecisions(0), decision_path(1) ,
{ ndecisions(0), decision_path(1) {
//printf("trapping here\n"); // printf("trapping here\n");
//assembler->trap(); // assembler->trap();
//for (int i = 0; i < num_temp_regs; i++) { // for (int i = 0; i < num_temp_regs; i++) {
//icentry->push(-2 - i); // icentry->push(-2 - i);
//} //}
#ifndef NDEBUG #ifndef NDEBUG
for (int i = -3; i < MAX_ARGS; i++) { for (int i = -3; i < MAX_ARGS; i++) {
...@@ -279,7 +281,7 @@ void Rewriter::addPush(int version) { ...@@ -279,7 +281,7 @@ void Rewriter::addPush(int version) {
RewriterVar Rewriter::alloca_(int bytes, int dest_argnum) { RewriterVar Rewriter::alloca_(int bytes, int dest_argnum) {
// TODO should check to make sure we aren't crossing push+pops and allocas // 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); assert(bytes % sizeof(void*) == 0);
alloca_bytes += bytes; alloca_bytes += bytes;
...@@ -314,7 +316,7 @@ int Rewriter::mutate(int argnum) { ...@@ -314,7 +316,7 @@ int Rewriter::mutate(int argnum) {
assert(versions.count(argnum)); assert(versions.count(argnum));
int rtn_version = ++next_version; 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; versions[argnum] = rtn_version;
return rtn_version; return rtn_version;
} }
...@@ -357,7 +359,7 @@ RewriterVar Rewriter::call(void* func_addr) { ...@@ -357,7 +359,7 @@ RewriterVar Rewriter::call(void* func_addr) {
#ifndef NDEBUG #ifndef NDEBUG
changed_something = true; changed_something = true;
#endif #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; int bytes = 8 * pushes.size() + alloca_bytes;
bool didpush; bool didpush;
...@@ -391,7 +393,7 @@ RewriterVar Rewriter::pop(int argnum) { ...@@ -391,7 +393,7 @@ RewriterVar Rewriter::pop(int argnum) {
#ifndef NDEBUG #ifndef NDEBUG
versions[argnum] = version; versions[argnum] = version;
#endif #endif
//printf("popping %d to %d\n", version, argnum); // printf("popping %d to %d\n", version, argnum);
assembler->pop(fromArgnum(argnum)); assembler->pop(fromArgnum(argnum));
return RewriterVar(this, argnum, version); return RewriterVar(this, argnum, version);
...@@ -403,7 +405,7 @@ void Rewriter::addDecision(int way) { ...@@ -403,7 +405,7 @@ void Rewriter::addDecision(int way) {
decision_path = (decision_path << 1) | way; decision_path = (decision_path << 1) | way;
} }
void Rewriter::addDependenceOn(ICInvalidator &invalidator) { void Rewriter::addDependenceOn(ICInvalidator& invalidator) {
rewrite->addDependenceOn(invalidator); rewrite->addDependenceOn(invalidator);
} }
...@@ -426,5 +428,4 @@ void Rewriter::finishAssembly(int continue_offset) { ...@@ -426,5 +428,4 @@ void Rewriter::finishAssembly(int continue_offset) {
assembler->pop(RAX); assembler->pop(RAX);
} }
} }
} }
...@@ -36,15 +36,15 @@ class Assembler; ...@@ -36,15 +36,15 @@ class Assembler;
// and a release one, instead of trying to make one class do both? // and a release one, instead of trying to make one class do both?
class RewriterVar { class RewriterVar {
private: private:
Rewriter *rewriter; Rewriter* rewriter;
int argnum; int argnum;
int version; int version;
public: public:
RewriterVar() : rewriter(NULL), argnum(-100), version(-100) {} RewriterVar() : rewriter(NULL), argnum(-100), version(-100) {}
RewriterVar(Rewriter *rewriter, int argnum, int version); RewriterVar(Rewriter* rewriter, int argnum, int version);
RewriterVar& operator=(const RewriterVar &rhs); RewriterVar& operator=(const RewriterVar& rhs);
#ifndef NDEBUG #ifndef NDEBUG
void assertValid() const; void assertValid() const;
...@@ -64,20 +64,20 @@ class RewriterVar { ...@@ -64,20 +64,20 @@ class RewriterVar {
RewriterVar getAttr(int offset, int dest); RewriterVar getAttr(int offset, int dest);
void incAttr(int offset); void incAttr(int offset);
void setAttr(int offset, const RewriterVar &val, bool user_visible=true); void setAttr(int offset, const RewriterVar& val, bool user_visible = true);
RewriterVar move(int argnum); RewriterVar move(int argnum);
bool isInReg(); bool isInReg();
void push(); void push();
RewriterVar cmp(AST_TYPE::AST_TYPE cmp_type, const RewriterVar &val, int dest); RewriterVar cmp(AST_TYPE::AST_TYPE cmp_type, const RewriterVar& val, int dest);
RewriterVar toBool(int dest); RewriterVar toBool(int dest);
friend class Rewriter; friend class Rewriter;
}; };
class Rewriter : public ICSlotRewrite::CommitHook { class Rewriter : public ICSlotRewrite::CommitHook {
private: private:
std::unique_ptr<ICSlotRewrite> rewrite; std::unique_ptr<ICSlotRewrite> rewrite;
assembler::Assembler *assembler; assembler::Assembler* assembler;
const int num_orig_args; const int num_orig_args;
const int num_temp_regs; const int num_temp_regs;
...@@ -98,7 +98,8 @@ class Rewriter : public ICSlotRewrite::CommitHook { ...@@ -98,7 +98,8 @@ class Rewriter : public ICSlotRewrite::CommitHook {
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); void addPush(int version);
public:
public:
static Rewriter* createRewriter(void* ic_rtn_addr, int num_orig_args, int num_temp_regs, const char* debug_name); static Rewriter* createRewriter(void* ic_rtn_addr, int num_orig_args, int num_temp_regs, const char* debug_name);
#ifndef NDEBUG #ifndef NDEBUG
...@@ -132,7 +133,6 @@ class Rewriter : public ICSlotRewrite::CommitHook { ...@@ -132,7 +133,6 @@ class Rewriter : public ICSlotRewrite::CommitHook {
friend class RewriterVar; friend class RewriterVar;
}; };
} }
#endif #endif
This diff is collapsed.
...@@ -31,22 +31,21 @@ class ICInvalidator; ...@@ -31,22 +31,21 @@ class ICInvalidator;
class RewriterVar2; class RewriterVar2;
struct Location { struct Location {
public: public:
enum LocationType : uint8_t { enum LocationType : uint8_t {
Register, Register,
XMMRegister, XMMRegister,
//Stack, // Stack,
Scratch, // stack location, relative to the scratch start Scratch, // stack location, relative to the scratch start
// For representing constants that fit in 32-bits, that can be encoded as immediates // For representing constants that fit in 32-bits, that can be encoded as immediates
Constant, Constant,
AnyReg, // special type for use when specifying a location as a destination AnyReg, // special type for use when specifying a location as a destination
None, // special type that represents the lack of a location, ex where a "ret void" gets returned None, // special type that represents the lack of a location, ex where a "ret void" gets returned
Uninitialized, // special type for an uninitialized (and invalid) location Uninitialized, // special type for an uninitialized (and invalid) location
}; };
public: public:
LocationType type; LocationType type;
union { union {
...@@ -66,24 +65,24 @@ struct Location { ...@@ -66,24 +65,24 @@ struct Location {
}; };
constexpr Location() : type(Uninitialized), _data(-1) {} constexpr Location() : type(Uninitialized), _data(-1) {}
constexpr Location(const Location &r) : type(r.type), _data(r._data) {} constexpr Location(const Location& r) : type(r.type), _data(r._data) {}
Location operator=(const Location &r) { Location operator=(const Location& r) {
type = r.type; type = r.type;
_data = r._data; _data = r._data;
return *this; return *this;
} }
constexpr Location(LocationType type, int32_t data) : type(type), _data(data) { constexpr Location(LocationType type, int32_t data) : type(type), _data(data) {}
}
constexpr Location(assembler::Register reg) : type(Register), regnum(reg.regnum) { constexpr Location(assembler::Register reg) : type(Register), regnum(reg.regnum) {}
}
constexpr Location(assembler::XMMRegister reg) : type(XMMRegister), regnum(reg.regnum) { constexpr Location(assembler::XMMRegister reg) : type(XMMRegister), regnum(reg.regnum) {}
}
constexpr Location(assembler::GenericRegister reg) : type(reg.type == assembler::GenericRegister::GP ? Register : reg.type == assembler::GenericRegister::XMM ? XMMRegister : None), regnum(reg.type == assembler::GenericRegister::GP ? reg.gp.regnum : reg.xmm.regnum) { constexpr Location(assembler::GenericRegister reg)
} : type(reg.type == assembler::GenericRegister::GP ? Register : reg.type == assembler::GenericRegister::XMM
? XMMRegister
: None),
regnum(reg.type == assembler::GenericRegister::GP ? reg.gp.regnum : reg.xmm.regnum) {}
assembler::Register asRegister() const; assembler::Register asRegister() const;
assembler::XMMRegister asXMMRegister() const; assembler::XMMRegister asXMMRegister() const;
...@@ -93,43 +92,34 @@ struct Location { ...@@ -93,43 +92,34 @@ struct Location {
static constexpr Location none() { return Location(None, 0); } static constexpr Location none() { return Location(None, 0); }
static Location forArg(int argnum); static Location forArg(int argnum);
bool operator==(const Location rhs) const { bool operator==(const Location rhs) const { return this->asInt() == rhs.asInt(); }
return this->asInt() == rhs.asInt();
}
bool operator!=(const Location rhs) const { bool operator!=(const Location rhs) const { return !(*this == rhs); }
return !(*this == rhs);
}
uint64_t asInt() const { uint64_t asInt() const { return (int)type + ((uint64_t)_data << 4); }
return (int)type + ((uint64_t)_data << 4);
}
void dump() const; void dump() const;
}; };
static_assert(sizeof(Location) <= 8, ""); static_assert(sizeof(Location) <= 8, "");
} }
namespace std { namespace std {
template <> struct hash<pyston::Location> { template <> struct hash<pyston::Location> {
size_t operator() (const pyston::Location p) const { size_t operator()(const pyston::Location p) const { return p.asInt(); }
return p.asInt(); };
}
};
} }
namespace pyston { namespace pyston {
class RewriterVarUsage2 { class RewriterVarUsage2 {
public: public:
enum KillFlag { enum KillFlag {
NoKill, NoKill,
Kill, Kill,
}; };
private: private:
RewriterVar2 *var; RewriterVar2* var;
bool done_using; bool done_using;
RewriterVarUsage2(); RewriterVarUsage2();
...@@ -141,15 +131,15 @@ class RewriterVarUsage2 { ...@@ -141,15 +131,15 @@ class RewriterVarUsage2 {
assert(!done_using); assert(!done_using);
} }
public: public:
// Creates a new Usage object of this var; ownership of // Creates a new Usage object of this var; ownership of
// one use of the var gets passed to this new object. // one use of the var gets passed to this new object.
RewriterVarUsage2(RewriterVar2 *var); RewriterVarUsage2(RewriterVar2* var);
// Move constructor; don't need it for performance reasons, but because // Move constructor; don't need it for performance reasons, but because
// semantically we have to pass the ownership of the use. // semantically we have to pass the ownership of the use.
RewriterVarUsage2(RewriterVarUsage2 &&usage); RewriterVarUsage2(RewriterVarUsage2&& usage);
RewriterVarUsage2& operator=(RewriterVarUsage2 &&usage); RewriterVarUsage2& operator=(RewriterVarUsage2&& usage);
// assert(this->var == NULL) // assert(this->var == NULL)
// assert(this->done_using) // assert(this->done_using)
// assert(usage->var != NULL) // assert(usage->var != NULL)
...@@ -158,24 +148,22 @@ class RewriterVarUsage2 { ...@@ -158,24 +148,22 @@ class RewriterVarUsage2 {
static RewriterVarUsage2 empty(); static RewriterVarUsage2 empty();
#ifndef NDEBUG #ifndef NDEBUG
~RewriterVarUsage2() { ~RewriterVarUsage2() { assert(done_using); }
assert(done_using);
}
#endif #endif
void setDoneUsing(); void setDoneUsing();
//void setDoneUsing() { // void setDoneUsing() {
//assert(!done_using); // assert(!done_using);
//done_using = true; // done_using = true;
// //
//var->delUse(); // var->delUse();
//} //}
//RewriterVarUsage2 addUse() { return var->addUse(); } // RewriterVarUsage2 addUse() { return var->addUse(); }
RewriterVarUsage2 addUse(); RewriterVarUsage2 addUse();
void addAttrGuard(int offset, uint64_t val); void addAttrGuard(int offset, uint64_t val);
RewriterVarUsage2 getAttr(int offset, KillFlag kill, Location loc=Location::any()); RewriterVarUsage2 getAttr(int offset, KillFlag kill, Location loc = Location::any());
void setAttr(int offset, RewriterVarUsage2 other); void setAttr(int offset, RewriterVarUsage2 other);
friend class Rewriter2; friend class Rewriter2;
...@@ -185,8 +173,8 @@ class Rewriter2; ...@@ -185,8 +173,8 @@ class Rewriter2;
// This might make more sense as an inner class of Rewriter2, but // This might make more sense as an inner class of Rewriter2, but
// you can't forward-declare that :/ // you can't forward-declare that :/
class RewriterVar2 { class RewriterVar2 {
private: private:
Rewriter2 *rewriter; Rewriter2* rewriter;
int num_uses; int num_uses;
std::unordered_set<Location> locations; std::unordered_set<Location> locations;
...@@ -195,15 +183,15 @@ class RewriterVar2 { ...@@ -195,15 +183,15 @@ class RewriterVar2 {
// Gets a copy of this variable in a register, spilling/reloading if necessary. // Gets a copy of this variable in a register, spilling/reloading if necessary.
// TODO have to be careful with the result since the interface doesn't guarantee // TODO have to be careful with the result since the interface doesn't guarantee
// that the register will still contain your value when you go to use it // that the register will still contain your value when you go to use it
assembler::Register getInReg(Location l=Location::any()); assembler::Register getInReg(Location l = Location::any());
assembler::XMMRegister getInXMMReg(Location l=Location::any()); assembler::XMMRegister getInXMMReg(Location l = Location::any());
// If this is an immediate, try getting it as one // If this is an immediate, try getting it as one
assembler::Immediate tryGetAsImmediate(bool *is_immediate); assembler::Immediate tryGetAsImmediate(bool* is_immediate);
void dump(); void dump();
public: public:
void incUse(); void incUse();
void decUse(); void decUse();
...@@ -217,7 +205,7 @@ class RewriterVar2 { ...@@ -217,7 +205,7 @@ class RewriterVar2 {
}; };
class Rewriter2 : public ICSlotRewrite::CommitHook { class Rewriter2 : public ICSlotRewrite::CommitHook {
private: private:
std::unique_ptr<ICSlotRewrite> rewrite; std::unique_ptr<ICSlotRewrite> rewrite;
assembler::Assembler* assembler; assembler::Assembler* assembler;
...@@ -235,7 +223,7 @@ class Rewriter2 : public ICSlotRewrite::CommitHook { ...@@ -235,7 +223,7 @@ class Rewriter2 : public ICSlotRewrite::CommitHook {
void assertChangesOk() { assert(done_guarding); } void assertChangesOk() { assert(done_guarding); }
void kill(RewriterVar2 *var); void kill(RewriterVar2* var);
// Allocates a register. dest must be of type Register or AnyReg // Allocates a register. dest must be of type Register or AnyReg
assembler::Register allocReg(Location dest); assembler::Register allocReg(Location dest);
...@@ -251,13 +239,13 @@ class Rewriter2 : public ICSlotRewrite::CommitHook { ...@@ -251,13 +239,13 @@ class Rewriter2 : public ICSlotRewrite::CommitHook {
// Given an empty location, do the internal bookkeeping to create a new var out of that location. // Given an empty location, do the internal bookkeeping to create a new var out of that location.
RewriterVarUsage2 createNewVar(Location dest); RewriterVarUsage2 createNewVar(Location dest);
// Do the bookkeeping to say that var is now also in location l // Do the bookkeeping to say that var is now also in location l
void addLocationToVar(RewriterVar2 *var, Location l); void addLocationToVar(RewriterVar2* var, Location l);
// Do the bookkeeping to say that var is no longer in location l // Do the bookkeeping to say that var is no longer in location l
void removeLocationFromVar(RewriterVar2 *var, Location l); void removeLocationFromVar(RewriterVar2* var, Location l);
void finishAssembly(int continue_offset) override; void finishAssembly(int continue_offset) override;
public: public:
// This should be called exactly once for each argument // This should be called exactly once for each argument
RewriterVarUsage2 getArg(int argnum); RewriterVarUsage2 getArg(int argnum);
...@@ -269,7 +257,7 @@ class Rewriter2 : public ICSlotRewrite::CommitHook { ...@@ -269,7 +257,7 @@ class Rewriter2 : public ICSlotRewrite::CommitHook {
TypeRecorder* getTypeRecorder(); TypeRecorder* getTypeRecorder();
void trap(); void trap();
RewriterVarUsage2 loadConst(int64_t val, Location loc=Location::any()); RewriterVarUsage2 loadConst(int64_t val, Location loc = Location::any());
RewriterVarUsage2 call(bool can_call_into_python, void* func_addr, std::vector<RewriterVarUsage2> args); RewriterVarUsage2 call(bool can_call_into_python, void* func_addr, std::vector<RewriterVarUsage2> args);
RewriterVarUsage2 call(bool can_call_into_python, void* func_addr, RewriterVarUsage2 arg0); RewriterVarUsage2 call(bool can_call_into_python, void* func_addr, RewriterVarUsage2 arg0);
RewriterVarUsage2 call(bool can_call_into_python, void* func_addr, RewriterVarUsage2 arg0, RewriterVarUsage2 arg1); RewriterVarUsage2 call(bool can_call_into_python, void* func_addr, RewriterVarUsage2 arg0, RewriterVarUsage2 arg1);
...@@ -284,7 +272,6 @@ class Rewriter2 : public ICSlotRewrite::CommitHook { ...@@ -284,7 +272,6 @@ class Rewriter2 : public ICSlotRewrite::CommitHook {
friend class RewriterVar2; friend class RewriterVar2;
friend class RewriterVarUsage2; friend class RewriterVarUsage2;
}; };
} }
#endif #endif
...@@ -36,13 +36,9 @@ struct Register { ...@@ -36,13 +36,9 @@ struct Register {
bool isCalleeSave(); bool isCalleeSave();
bool operator==(const Register &rhs) const { bool operator==(const Register& rhs) const { return regnum == rhs.regnum; }
return regnum == rhs.regnum;
}
bool operator!=(const Register &rhs) const { bool operator!=(const Register& rhs) const { return !(*this == rhs); }
return !(*this == rhs);
}
void dump() const; void dump() const;
}; };
...@@ -69,7 +65,7 @@ inline bool Register::isCalleeSave() { ...@@ -69,7 +65,7 @@ inline bool Register::isCalleeSave() {
} }
struct Indirect { struct Indirect {
public: public:
const Register base; const Register base;
const int offset; const int offset;
...@@ -81,13 +77,9 @@ struct XMMRegister { ...@@ -81,13 +77,9 @@ struct XMMRegister {
explicit constexpr XMMRegister(int regnum) : regnum(regnum) {} explicit constexpr XMMRegister(int regnum) : regnum(regnum) {}
bool operator==(const XMMRegister &rhs) const { bool operator==(const XMMRegister& rhs) const { return regnum == rhs.regnum; }
return regnum == rhs.regnum;
}
bool operator!=(const XMMRegister &rhs) const { bool operator!=(const XMMRegister& rhs) const { return !(*this == rhs); }
return !(*this == rhs);
}
}; };
const XMMRegister XMM0(0); const XMMRegister XMM0(0);
...@@ -157,7 +149,6 @@ struct JumpDestination { ...@@ -157,7 +149,6 @@ struct JumpDestination {
constexpr JumpDestination(OffsetType type, int offset) : type(type), offset(offset) {} constexpr JumpDestination(OffsetType type, int offset) : type(type), offset(offset) {}
static JumpDestination fromStart(int offset) { return JumpDestination(FROM_START, offset); } static JumpDestination fromStart(int offset) { return JumpDestination(FROM_START, offset); }
}; };
} }
} }
......
...@@ -28,7 +28,8 @@ ...@@ -28,7 +28,8 @@
namespace pyston { 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(addr);
assert(functions.count(addr) == 0); assert(functions.count(addr) == 0);
functions.insert(std::make_pair(addr, FuncInfo(name, length, llvm_func))); functions.insert(std::make_pair(addr, FuncInfo(name, length, llvm_func)));
...@@ -42,19 +43,19 @@ void FunctionAddressRegistry::dumpPerfMap() { ...@@ -42,19 +43,19 @@ void FunctionAddressRegistry::dumpPerfMap() {
code = llvm::sys::fs::create_directory(out_path, false); code = llvm::sys::fs::create_directory(out_path, false);
assert(!code); 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]; char buf[80];
snprintf(buf, 80, "/tmp/perf-%d.map", getpid()); snprintf(buf, 80, "/tmp/perf-%d.map", getpid());
FILE *f = fopen(buf, "w"); FILE* f = fopen(buf, "w");
for (const auto &p : functions) { for (const auto& p : functions) {
const FuncInfo& info = p.second; const FuncInfo& info = p.second;
fprintf(f, "%lx %x %s\n", (uintptr_t)p.first, info.length, info.name.c_str()); fprintf(f, "%lx %x %s\n", (uintptr_t)p.first, info.length, info.name.c_str());
if (info.length > 0) { if (info.length > 0) {
fprintf(index_f, "%lx %s\n", (uintptr_t)p.first, info.name.c_str()); 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); int written = fwrite((void*)p.first, 1, info.length, data_f);
assert(written == info.length); assert(written == info.length);
...@@ -77,7 +78,7 @@ llvm::Function* FunctionAddressRegistry::getLLVMFuncAtAddress(void* addr) { ...@@ -77,7 +78,7 @@ llvm::Function* FunctionAddressRegistry::getLLVMFuncAtAddress(void* addr) {
return NULL; return NULL;
} }
llvm::Function *r = g.stdlib_module->getFunction(name); llvm::Function* r = g.stdlib_module->getFunction(name);
if (!r) { if (!r) {
lookup_neg_cache.insert(addr); lookup_neg_cache.insert(addr);
...@@ -101,7 +102,7 @@ static std::string tryDemangle(const char* s) { ...@@ -101,7 +102,7 @@ static std::string tryDemangle(const char* s) {
return rtn; 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); FuncMap::iterator it = functions.find(addr);
if (it == functions.end()) { if (it == functions.end()) {
Dl_info info; Dl_info info;
...@@ -110,8 +111,9 @@ std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool deman ...@@ -110,8 +111,9 @@ std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool deman
if (success && info.dli_sname == NULL) if (success && info.dli_sname == NULL)
success = false; success = false;
if (out_success) *out_success = success; if (out_success)
//if (success && info.dli_saddr == addr) { *out_success = success;
// if (success && info.dli_saddr == addr) {
if (success) { if (success) {
if (demangle) if (demangle)
return tryDemangle(info.dli_sname); return tryDemangle(info.dli_sname);
...@@ -121,7 +123,8 @@ std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool deman ...@@ -121,7 +123,8 @@ std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool deman
return "<unknown>"; return "<unknown>";
} }
if (out_success) *out_success = true; if (out_success)
*out_success = true;
if (!demangle) if (!demangle)
return it->second.name; return it->second.name;
...@@ -129,8 +132,8 @@ std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool deman ...@@ -129,8 +132,8 @@ std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool deman
} }
class RegistryEventListener : public llvm::JITEventListener { class RegistryEventListener : public llvm::JITEventListener {
public: public:
void NotifyObjectEmitted(const llvm::ObjectImage &Obj) { void NotifyObjectEmitted(const llvm::ObjectImage& Obj) {
static StatCounter code_bytes("code_bytes"); static StatCounter code_bytes("code_bytes");
code_bytes.log(Obj.getData().size()); code_bytes.log(Obj.getData().size());
...@@ -165,17 +168,15 @@ class RegistryEventListener : public llvm::JITEventListener { ...@@ -165,17 +168,15 @@ class RegistryEventListener : public llvm::JITEventListener {
if (name == ".text") if (name == ".text")
continue; continue;
//printf("%lx %lx %lx %s\n", addr, addr + size, offset, name.data()); // printf("%lx %lx %lx %s\n", addr, addr + size, offset, name.data());
g.func_addr_registry.registerFunction(name.data(), (void*)addr, size, NULL); g.func_addr_registry.registerFunction(name.data(), (void*)addr, size, NULL);
} }
} }
}; };
GlobalState::GlobalState() : context(llvm::getGlobalContext()) { GlobalState::GlobalState() : context(llvm::getGlobalContext()) {};
};
llvm::JITEventListener* makeRegistryListener() { llvm::JITEventListener* makeRegistryListener() {
return new RegistryEventListener(); return new RegistryEventListener();
} }
} }
...@@ -36,23 +36,22 @@ namespace pyston { ...@@ -36,23 +36,22 @@ namespace pyston {
class PystonJITEventListener; class PystonJITEventListener;
class FunctionAddressRegistry { class FunctionAddressRegistry {
private: private:
struct FuncInfo { struct FuncInfo {
std::string name; std::string name;
int length; int length;
llvm::Function *llvm_func; llvm::Function* llvm_func;
FuncInfo(const std::string& name, int length, llvm::Function *llvm_func) : FuncInfo(const std::string& name, int length, llvm::Function* llvm_func)
name(name), length(length), llvm_func(llvm_func) { : name(name), length(length), llvm_func(llvm_func) {}
}
}; };
typedef std::unordered_map<void*, FuncInfo> FuncMap; typedef std::unordered_map<void*, FuncInfo> FuncMap;
FuncMap functions; FuncMap functions;
std::unordered_set<void*> lookup_neg_cache; std::unordered_set<void*> lookup_neg_cache;
public: public:
std::string getFuncNameAtAddress(void* addr, bool demangle, bool *out_success=NULL); std::string getFuncNameAtAddress(void* addr, bool demangle, bool* out_success = NULL);
llvm::Function* getLLVMFuncAtAddress(void* addr); llvm::Function* getLLVMFuncAtAddress(void* addr);
void registerFunction(const std::string &name, void *addr, int length, llvm::Function* llvm_func); void registerFunction(const std::string& name, void* addr, int length, llvm::Function* llvm_func);
void dumpPerfMap(); void dumpPerfMap();
}; };
...@@ -60,22 +59,22 @@ llvm::JITEventListener* makeRegistryListener(); ...@@ -60,22 +59,22 @@ llvm::JITEventListener* makeRegistryListener();
llvm::JITEventListener* makeTracebacksListener(); llvm::JITEventListener* makeTracebacksListener();
struct GlobalState { struct GlobalState {
llvm::LLVMContext &context; llvm::LLVMContext& context;
llvm::Module *stdlib_module, *cur_module; llvm::Module* stdlib_module, *cur_module;
llvm::TargetMachine *tm; llvm::TargetMachine* tm;
llvm::ExecutionEngine *engine; llvm::ExecutionEngine* engine;
std::vector<llvm::JITEventListener*> jit_listeners; std::vector<llvm::JITEventListener*> jit_listeners;
FunctionAddressRegistry func_addr_registry; FunctionAddressRegistry func_addr_registry;
llvm::Type *llvm_value_type, *llvm_value_type_ptr; llvm::Type* llvm_value_type, *llvm_value_type_ptr;
llvm::Type *llvm_class_type, *llvm_class_type_ptr; llvm::Type* llvm_class_type, *llvm_class_type_ptr;
llvm::Type *llvm_flavor_type, *llvm_flavor_type_ptr; llvm::Type* llvm_flavor_type, *llvm_flavor_type_ptr;
llvm::Type *llvm_opaque_type; llvm::Type* llvm_opaque_type;
llvm::Type *llvm_str_type_ptr; llvm::Type* llvm_str_type_ptr;
llvm::Type *llvm_clfunction_type_ptr; llvm::Type* llvm_clfunction_type_ptr;
llvm::Type *llvm_module_type_ptr, *llvm_bool_type_ptr; llvm::Type* llvm_module_type_ptr, *llvm_bool_type_ptr;
llvm::Type *i1, *i8, *i8_ptr, *i32, *i64, *void_, *double_; llvm::Type* i1, *i8, *i8_ptr, *i32, *i64, *void_, *double_;
GlobalFuncs funcs; GlobalFuncs funcs;
...@@ -85,9 +84,7 @@ struct GlobalState { ...@@ -85,9 +84,7 @@ struct GlobalState {
extern GlobalState g; extern GlobalState g;
// in runtime_hooks.cpp: // in runtime_hooks.cpp:
void initGlobalFuncs(GlobalState &g); void initGlobalFuncs(GlobalState& g);
} }
#endif #endif
This diff is collapsed.
This diff is collapsed.
...@@ -46,47 +46,46 @@ PystonJITEventListener::PystonJITEventListener() { ...@@ -46,47 +46,46 @@ PystonJITEventListener::PystonJITEventListener() {
llvm::InitializeNativeTargetDisassembler(); llvm::InitializeNativeTargetDisassembler();
std::string err; std::string err;
const llvm::Target *target = llvm::TargetRegistry::getClosestTargetForJIT(err); const llvm::Target* target = llvm::TargetRegistry::getClosestTargetForJIT(err);
assert(target); assert(target);
const llvm::StringRef triple = g.tm->getTargetTriple(); const llvm::StringRef triple = g.tm->getTargetTriple();
//llvm::Triple *ltriple = new llvm::Triple(triple); // llvm::Triple *ltriple = new llvm::Triple(triple);
const llvm::StringRef CPU = ""; const llvm::StringRef CPU = "";
const llvm::MCRegisterInfo *MRI = target->createMCRegInfo(triple); const llvm::MCRegisterInfo* MRI = target->createMCRegInfo(triple);
assert(MRI); assert(MRI);
const llvm::MCAsmInfo *MAI = target->createMCAsmInfo(*MRI, triple); const llvm::MCAsmInfo* MAI = target->createMCAsmInfo(*MRI, triple);
assert(MAI); assert(MAI);
const llvm::MCInstrInfo *MII = target->createMCInstrInfo(); const llvm::MCInstrInfo* MII = target->createMCInstrInfo();
assert(MII); assert(MII);
std::string FeaturesStr; std::string FeaturesStr;
const llvm::MCSubtargetInfo *STI = target->createMCSubtargetInfo(triple, CPU, FeaturesStr); const llvm::MCSubtargetInfo* STI = target->createMCSubtargetInfo(triple, CPU, FeaturesStr);
assert(STI); assert(STI);
llvm::MCObjectFileInfo *MOFI = new llvm::MCObjectFileInfo(); llvm::MCObjectFileInfo* MOFI = new llvm::MCObjectFileInfo();
llvm::MCContext *Ctx = new llvm::MCContext(MAI, MRI, MOFI); llvm::MCContext* Ctx = new llvm::MCContext(MAI, MRI, MOFI);
assert(Ctx); assert(Ctx);
assert(Ctx->getObjectFileInfo()); assert(Ctx->getObjectFileInfo());
MOFI->InitMCObjectFileInfo(triple, llvm::Reloc::Default, llvm::CodeModel::Default, *Ctx); MOFI->InitMCObjectFileInfo(triple, llvm::Reloc::Default, llvm::CodeModel::Default, *Ctx);
llvm::MCAsmBackend *TAB = target->createMCAsmBackend(*MRI, triple, CPU); llvm::MCAsmBackend* TAB = target->createMCAsmBackend(*MRI, triple, CPU);
assert(TAB); assert(TAB);
int AsmPrinterVariant = MAI->getAssemblerDialect(); // 0 is ATT, 1 is Intel int AsmPrinterVariant = MAI->getAssemblerDialect(); // 0 is ATT, 1 is Intel
IP = target->createMCInstPrinter(AsmPrinterVariant, IP = target->createMCInstPrinter(AsmPrinterVariant, *MAI, *MII, *MRI, *STI);
*MAI, *MII, *MRI, *STI);
assert(IP); assert(IP);
llvm::MCCodeEmitter *CE = target->createMCCodeEmitter(*MII, *MRI, *STI, *Ctx); llvm::MCCodeEmitter* CE = target->createMCCodeEmitter(*MII, *MRI, *STI, *Ctx);
assert(CE); assert(CE);
bool verbose = false; bool verbose = false;
llvm::MCStreamer *streamer = target->createAsmStreamer(*Ctx, llvm::ferrs(), verbose, true, true, IP, CE, TAB, true); llvm::MCStreamer* streamer = target->createAsmStreamer(*Ctx, llvm::ferrs(), verbose, true, true, IP, CE, TAB, true);
assert(streamer); assert(streamer);
streamer->InitSections(); streamer->InitSections();
streamer->SwitchSection(Ctx->getObjectFileInfo()->getTextSection()); streamer->SwitchSection(Ctx->getObjectFileInfo()->getTextSection());
...@@ -95,9 +94,10 @@ PystonJITEventListener::PystonJITEventListener() { ...@@ -95,9 +94,10 @@ PystonJITEventListener::PystonJITEventListener() {
assert(asm_printer); assert(asm_printer);
llvm::TargetOptions Options; llvm::TargetOptions Options;
llvm::TargetMachine *tmachine = target->createTargetMachine(triple, "", "", Options, llvm::Reloc::Default, llvm::CodeModel::Default, llvm::CodeGenOpt::Default); llvm::TargetMachine* tmachine = target->createTargetMachine(triple, "", "", Options, llvm::Reloc::Default,
llvm::CodeModel::Default, llvm::CodeGenOpt::Default);
//asm_printer->Mang = new llvm::Mangler(*Ctx, *tmachine->getDataLayout()); // asm_printer->Mang = new llvm::Mangler(*Ctx, *tmachine->getDataLayout());
asm_printer->Mang = new llvm::Mangler(tmachine->getDataLayout()); asm_printer->Mang = new llvm::Mangler(tmachine->getDataLayout());
...@@ -107,24 +107,23 @@ PystonJITEventListener::PystonJITEventListener() { ...@@ -107,24 +107,23 @@ PystonJITEventListener::PystonJITEventListener() {
assert(MIA); assert(MIA);
} }
void PystonJITEventListener::NotifyFunctionEmitted(const llvm::Function &f, void PystonJITEventListener::NotifyFunctionEmitted(const llvm::Function& f, void* ptr, size_t size,
void *ptr, size_t size, const llvm::JITEvent_EmittedFunctionDetails& details) {
const llvm::JITEvent_EmittedFunctionDetails &details) { const llvm::MachineFunction& MF = *details.MF; //*const_cast<llvm::MachineFunction*>(details.MF);
const llvm::MachineFunction &MF = *details.MF;//*const_cast<llvm::MachineFunction*>(details.MF);
printf("emitted! %p %ld %s\n", ptr, size, f.getName().data()); printf("emitted! %p %ld %s\n", ptr, size, f.getName().data());
//MF.dump(); // MF.dump();
//MF.print(llvm::errs()); // MF.print(llvm::errs());
asm_printer->MF = &MF; asm_printer->MF = &MF;
for (llvm::MachineFunction::const_iterator it = MF.begin(); it != MF.end(); it++) { for (llvm::MachineFunction::const_iterator it = MF.begin(); it != MF.end(); it++) {
//it->dump(); // it->dump();
asm_printer->EmitBasicBlockStart(it); asm_printer->EmitBasicBlockStart(it);
for (llvm::MachineBasicBlock::const_instr_iterator it2 = it->instr_begin(); it2 != it->instr_end(); it2++) { for (llvm::MachineBasicBlock::const_instr_iterator it2 = it->instr_begin(); it2 != it->instr_end(); it2++) {
//llvm::errs() << "dump:"; // llvm::errs() << "dump:";
//it2->print(llvm::errs()); // it2->print(llvm::errs());
if (it2->getNumOperands() && (it2->getOperand(0).getType() == llvm::MachineOperand::MO_MCSymbol)) { if (it2->getNumOperands() && (it2->getOperand(0).getType() == llvm::MachineOperand::MO_MCSymbol)) {
//it2->print(llvm::errs()); // it2->print(llvm::errs());
//it2->getOperand(0).print(llvm::errs()); // it2->getOperand(0).print(llvm::errs());
llvm::errs() << it2->getOperand(0).getMCSymbol()->getName() << '\n'; llvm::errs() << it2->getOperand(0).getMCSymbol()->getName() << '\n';
} else { } else {
asm_printer->EmitInstruction(it2); asm_printer->EmitInstruction(it2);
...@@ -135,7 +134,7 @@ void PystonJITEventListener::NotifyFunctionEmitted(const llvm::Function &f, ...@@ -135,7 +134,7 @@ void PystonJITEventListener::NotifyFunctionEmitted(const llvm::Function &f,
llvm::errs().flush(); llvm::errs().flush();
} }
void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) { void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage& Obj) {
llvm::outs() << "An object has been emitted:\n"; llvm::outs() << "An object has been emitted:\n";
llvm::error_code code; llvm::error_code code;
...@@ -147,10 +146,22 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) { ...@@ -147,10 +146,22 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
const char* type = "unknown"; const char* type = "unknown";
bool b; bool b;
code = I->isText(b); assert(!code); if (b) type = "text"; code = I->isText(b);
code = I->isData(b); assert(!code); if (b) type = "data"; assert(!code);
code = I->isBSS(b); assert(!code); if (b) type = "bss"; if (b)
code = I->isReadOnlyData(b); assert(!code); if (b) type = "rodata"; type = "text";
code = I->isData(b);
assert(!code);
if (b)
type = "data";
code = I->isBSS(b);
assert(!code);
if (b)
type = "bss";
code = I->isReadOnlyData(b);
assert(!code);
if (b)
type = "rodata";
printf("Section: %s %s\n", name.data(), type); printf("Section: %s %s\n", name.data(), type);
#if LLVMREV < 200442 #if LLVMREV < 200442
...@@ -179,8 +190,8 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) { ...@@ -179,8 +190,8 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
#endif #endif
} }
llvm::MCObjectDisassembler *OD = new llvm::MCObjectDisassembler(*Obj.getObjectFile(), *DisAsm, *MIA); llvm::MCObjectDisassembler* OD = new llvm::MCObjectDisassembler(*Obj.getObjectFile(), *DisAsm, *MIA);
llvm::MCModule *Mod = OD->buildModule(true); llvm::MCModule* Mod = OD->buildModule(true);
// This is taken from llvm-objdump.cpp: // This is taken from llvm-objdump.cpp:
uint64_t text_start = 0; uint64_t text_start = 0;
...@@ -188,13 +199,13 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) { ...@@ -188,13 +199,13 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
llvm::outs() << "Atom " << (*AI)->getName() << ", starts at " << (void*)(*AI)->getBeginAddr() << ": \n"; llvm::outs() << "Atom " << (*AI)->getName() << ", starts at " << (void*)(*AI)->getBeginAddr() << ": \n";
if ((*AI)->getName() == ".text") if ((*AI)->getName() == ".text")
text_start = (*AI)->getBeginAddr(); text_start = (*AI)->getBeginAddr();
if (const llvm::MCTextAtom *TA = llvm::dyn_cast<llvm::MCTextAtom>(*AI)) { if (const llvm::MCTextAtom* TA = llvm::dyn_cast<llvm::MCTextAtom>(*AI)) {
for (llvm::MCTextAtom::const_iterator II = TA->begin(), IE = TA->end(); II != IE; ++II) { for (llvm::MCTextAtom::const_iterator II = TA->begin(), IE = TA->end(); II != IE; ++II) {
llvm::outs() << "0x"; llvm::outs() << "0x";
llvm::outs().write_hex(II->Address); llvm::outs().write_hex(II->Address);
//llvm::outs() << " (+0x"; // llvm::outs() << " (+0x";
//llvm::outs().write_hex(II->Address - text_start); // llvm::outs().write_hex(II->Address - text_start);
llvm::outs() << " (+" << II->Address - text_start; llvm::outs() << " (+" << II->Address - text_start;
llvm::outs() << ") "; llvm::outs() << ") ";
...@@ -206,5 +217,4 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) { ...@@ -206,5 +217,4 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
llvm::outs().flush(); llvm::outs().flush();
} }
} }
This diff is collapsed.
This diff is collapsed.
...@@ -25,8 +25,6 @@ void initCodegen(); ...@@ -25,8 +25,6 @@ void initCodegen();
void teardownCodegen(); void teardownCodegen();
void printAllIR(); void printAllIR();
int joinRuntime(); int joinRuntime();
} }
#endif #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.
...@@ -21,7 +21,6 @@ class AST_Module; ...@@ -21,7 +21,6 @@ class AST_Module;
AST_Module* parse(const char* fn); AST_Module* parse(const char* fn);
AST_Module* caching_parse(const char* fn); AST_Module* caching_parse(const char* fn);
} }
#endif #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.
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