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 @@
namespace pyston {
template <typename T>
class BBAnalyzer {
public:
template <typename T> class BBAnalyzer {
public:
typedef std::unordered_map<std::string, T> Map;
typedef std::unordered_map<CFGBlock*, Map> AllMap;
......@@ -32,11 +31,11 @@ class 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 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,11 +27,11 @@ 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:
public:
enum DefinitionLevel {
Undefined,
PotentiallyDefined,
......@@ -39,40 +39,38 @@ class DefinednessAnalysis {
};
typedef std::unordered_set<std::string> RequiredSet;
private:
private:
std::unordered_map<CFGBlock*, std::unordered_map<std::string, DefinitionLevel> > results;
std::unordered_map<CFGBlock*, const RequiredSet> defined;
ScopeInfo *scope_info;
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:
public:
typedef std::unordered_set<std::string> RequiredSet;
private:
private:
DefinednessAnalysis definedness;
LivenessAnalysis *liveness;
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:
public:
virtual ~ScopeInfo() {}
virtual ScopeInfo* getParent() = 0;
virtual bool createsClosure() = 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 saveInClosure(const std::string name) = 0;
};
class ScopingAnalysis {
public:
public:
struct ScopeNameUsage;
typedef std::unordered_map<AST*, ScopeNameUsage*> NameUsageMap;
private:
private:
std::unordered_map<AST*, ScopeInfo*> scopes;
AST_Module* parent_module;
ScopeInfo* analyzeSubtree(AST* node);
void processNameUsages(NameUsageMap* usages);
public:
ScopingAnalysis(AST_Module *m);
public:
ScopingAnalysis(AST_Module* m);
ScopeInfo* getScopeInfoForNode(AST* node);
};
ScopingAnalysis* runScopingAnalysis(AST_Module* m);
}
#endif
This diff is collapsed.
......@@ -26,7 +26,7 @@ namespace pyston {
class ScopeInfo;
class TypeAnalysis {
public:
public:
enum SpeculationLevel {
NONE,
SOME,
......@@ -34,14 +34,15 @@ class TypeAnalysis {
virtual ~TypeAnalysis() {}
virtual ConcreteCompilerType* getTypeAtBlockStart(const std::string &name, CFGBlock* block) = 0;
virtual ConcreteCompilerType* getTypeAtBlockEnd(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 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;
}
}
}
......@@ -49,13 +49,14 @@ enum ConditionCode {
};
class Assembler {
private:
uint8_t *const start_addr, *const end_addr;
uint8_t *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:
private:
void emitByte(uint8_t b);
void emitInt(int64_t n, int bytes);
void emitRex(uint8_t rex);
......@@ -63,7 +64,7 @@ class Assembler {
void emitSIB(uint8_t scalebits, uint8_t index, uint8_t base);
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) {}
void nop() { emitByte(0x90); }
......@@ -112,8 +113,8 @@ class Assembler {
// 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 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);
......@@ -121,8 +122,8 @@ class Assembler {
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) {
// 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);
// 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,34 +30,35 @@ class ICInfo;
class ICInvalidator;
struct ICSlotInfo {
public:
public:
ICSlotInfo(ICInfo* ic, int idx) : ic(ic), idx(idx) {}
ICInfo *ic;
ICInfo* ic;
int idx;
void clear();
};
class ICSlotRewrite {
public:
public:
class CommitHook {
public:
virtual ~CommitHook() {}
virtual void finishAssembly(int fastpath_offset) = 0;
};
private:
private:
ICInfo* ic;
assembler::Assembler* assembler;
const char* debug_name;
uint8_t *buf;
uint8_t* buf;
std::vector<std::pair<ICInvalidator*, int64_t> > dependencies;
ICSlotRewrite(ICInfo* ic, const char* debug_name);
public:
public:
~ICSlotRewrite();
assembler::Assembler* getAssembler() { return assembler; }
......@@ -71,13 +72,13 @@ class ICSlotRewrite {
assembler::GenericRegister returnRegister();
void addDependenceOn(ICInvalidator&);
void commit(uint64_t decision_path, CommitHook *hook);
void commit(uint64_t decision_path, CommitHook* hook);
friend class ICInfo;
};
class ICInfo {
private:
private:
struct SlotInfo {
bool is_patched;
uint64_t decision_path;
......@@ -98,16 +99,18 @@ class ICInfo {
const llvm::CallingConv::ID calling_conv;
const std::vector<int> live_outs;
const assembler::GenericRegister return_register;
TypeRecorder * const type_recorder;
TypeRecorder* const type_recorder;
// for ICSlotRewrite:
ICSlotInfo *pickEntryForRewrite(uint64_t decision_path, const char* debug_name);
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;
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; }
......@@ -115,17 +118,16 @@ class ICInfo {
const std::vector<int>& getLiveOuts() { return live_outs; }
ICSlotRewrite* startRewrite(const char* debug_name);
void clear(ICSlotInfo *entry);
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,7 +22,7 @@ namespace pyston {
class BoxedClass;
class MCWriter {
public:
public:
virtual ~MCWriter() {}
virtual int numArgRegs() = 0;
......@@ -50,12 +50,10 @@ class MCWriter {
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,15 +36,15 @@ class Assembler;
// and a release one, instead of trying to make one class do both?
class RewriterVar {
private:
Rewriter *rewriter;
private:
Rewriter* rewriter;
int argnum;
int version;
public:
public:
RewriterVar() : rewriter(NULL), argnum(-100), version(-100) {}
RewriterVar(Rewriter *rewriter, int argnum, int version);
RewriterVar& operator=(const RewriterVar &rhs);
RewriterVar(Rewriter* rewriter, int argnum, int version);
RewriterVar& operator=(const RewriterVar& rhs);
#ifndef NDEBUG
void assertValid() const;
......@@ -64,20 +64,20 @@ class RewriterVar {
RewriterVar getAttr(int offset, int dest);
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);
bool isInReg();
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);
friend class Rewriter;
};
class Rewriter : public ICSlotRewrite::CommitHook {
private:
private:
std::unique_ptr<ICSlotRewrite> rewrite;
assembler::Assembler *assembler;
assembler::Assembler* assembler;
const int num_orig_args;
const int num_temp_regs;
......@@ -98,7 +98,8 @@ class Rewriter : public ICSlotRewrite::CommitHook {
Rewriter(ICSlotRewrite* rewrite, int num_orig_args, int num_temp_regs);
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);
#ifndef NDEBUG
......@@ -132,7 +133,6 @@ class Rewriter : public ICSlotRewrite::CommitHook {
friend class RewriterVar;
};
}
#endif
This diff is collapsed.
......@@ -31,22 +31,21 @@ class ICInvalidator;
class RewriterVar2;
struct Location {
public:
public:
enum LocationType : uint8_t {
Register,
XMMRegister,
//Stack,
// Stack,
Scratch, // stack location, relative to the scratch start
// For representing constants that fit in 32-bits, that can be encoded as immediates
Constant,
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
Uninitialized, // special type for an uninitialized (and invalid) location
};
public:
public:
LocationType type;
union {
......@@ -66,24 +65,24 @@ struct Location {
};
constexpr Location() : type(Uninitialized), _data(-1) {}
constexpr Location(const Location &r) : type(r.type), _data(r._data) {}
Location operator=(const Location &r) {
constexpr Location(const Location& r) : type(r.type), _data(r._data) {}
Location operator=(const Location& r) {
type = r.type;
_data = r._data;
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::XMMRegister asXMMRegister() const;
......@@ -93,43 +92,34 @@ struct Location {
static constexpr Location none() { return Location(None, 0); }
static Location forArg(int argnum);
bool operator==(const Location rhs) const {
return this->asInt() == rhs.asInt();
}
bool operator==(const Location rhs) const { return this->asInt() == rhs.asInt(); }
bool operator!=(const Location rhs) const {
return !(*this == rhs);
}
bool operator!=(const Location rhs) const { return !(*this == rhs); }
uint64_t asInt() const {
return (int)type + ((uint64_t)_data << 4);
}
uint64_t asInt() const { return (int)type + ((uint64_t)_data << 4); }
void dump() const;
};
static_assert(sizeof(Location) <= 8, "");
}
namespace std {
template <> struct hash<pyston::Location> {
size_t operator() (const pyston::Location p) const {
return p.asInt();
}
};
template <> struct hash<pyston::Location> {
size_t operator()(const pyston::Location p) const { return p.asInt(); }
};
}
namespace pyston {
class RewriterVarUsage2 {
public:
public:
enum KillFlag {
NoKill,
Kill,
};
private:
RewriterVar2 *var;
private:
RewriterVar2* var;
bool done_using;
RewriterVarUsage2();
......@@ -141,15 +131,15 @@ class RewriterVarUsage2 {
assert(!done_using);
}
public:
public:
// Creates a new Usage object of this var; ownership of
// 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
// semantically we have to pass the ownership of the use.
RewriterVarUsage2(RewriterVarUsage2 &&usage);
RewriterVarUsage2& operator=(RewriterVarUsage2 &&usage);
RewriterVarUsage2(RewriterVarUsage2&& usage);
RewriterVarUsage2& operator=(RewriterVarUsage2&& usage);
// assert(this->var == NULL)
// assert(this->done_using)
// assert(usage->var != NULL)
......@@ -158,24 +148,22 @@ class RewriterVarUsage2 {
static RewriterVarUsage2 empty();
#ifndef NDEBUG
~RewriterVarUsage2() {
assert(done_using);
}
~RewriterVarUsage2() { assert(done_using); }
#endif
void setDoneUsing();
//void setDoneUsing() {
//assert(!done_using);
//done_using = true;
//
//var->delUse();
// void setDoneUsing() {
// assert(!done_using);
// done_using = true;
//
// var->delUse();
//}
//RewriterVarUsage2 addUse() { return var->addUse(); }
// RewriterVarUsage2 addUse() { return var->addUse(); }
RewriterVarUsage2 addUse();
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);
friend class Rewriter2;
......@@ -185,8 +173,8 @@ class Rewriter2;
// This might make more sense as an inner class of Rewriter2, but
// you can't forward-declare that :/
class RewriterVar2 {
private:
Rewriter2 *rewriter;
private:
Rewriter2* rewriter;
int num_uses;
std::unordered_set<Location> locations;
......@@ -195,15 +183,15 @@ class RewriterVar2 {
// 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
// that the register will still contain your value when you go to use it
assembler::Register getInReg(Location l=Location::any());
assembler::XMMRegister getInXMMReg(Location l=Location::any());
assembler::Register getInReg(Location l = Location::any());
assembler::XMMRegister getInXMMReg(Location l = Location::any());
// If this is an immediate, try getting it as one
assembler::Immediate tryGetAsImmediate(bool *is_immediate);
assembler::Immediate tryGetAsImmediate(bool* is_immediate);
void dump();
public:
public:
void incUse();
void decUse();
......@@ -217,7 +205,7 @@ class RewriterVar2 {
};
class Rewriter2 : public ICSlotRewrite::CommitHook {
private:
private:
std::unique_ptr<ICSlotRewrite> rewrite;
assembler::Assembler* assembler;
......@@ -235,7 +223,7 @@ class Rewriter2 : public ICSlotRewrite::CommitHook {
void assertChangesOk() { assert(done_guarding); }
void kill(RewriterVar2 *var);
void kill(RewriterVar2* var);
// Allocates a register. dest must be of type Register or AnyReg
assembler::Register allocReg(Location dest);
......@@ -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.
RewriterVarUsage2 createNewVar(Location dest);
// 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
void removeLocationFromVar(RewriterVar2 *var, Location l);
void removeLocationFromVar(RewriterVar2* var, Location l);
void finishAssembly(int continue_offset) override;
public:
public:
// This should be called exactly once for each argument
RewriterVarUsage2 getArg(int argnum);
......@@ -269,7 +257,7 @@ class Rewriter2 : public ICSlotRewrite::CommitHook {
TypeRecorder* getTypeRecorder();
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, RewriterVarUsage2 arg0);
RewriterVarUsage2 call(bool can_call_into_python, void* func_addr, RewriterVarUsage2 arg0, RewriterVarUsage2 arg1);
......@@ -284,7 +272,6 @@ class Rewriter2 : public ICSlotRewrite::CommitHook {
friend class RewriterVar2;
friend class RewriterVarUsage2;
};
}
#endif
......@@ -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,7 +65,7 @@ inline bool Register::isCalleeSave() {
}
struct Indirect {
public:
public:
const Register base;
const int offset;
......@@ -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,8 +132,8 @@ std::string FunctionAddressRegistry::getFuncNameAtAddress(void* addr, bool deman
}
class RegistryEventListener : public llvm::JITEventListener {
public:
void NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
public:
void NotifyObjectEmitted(const llvm::ObjectImage& Obj) {
static StatCounter code_bytes("code_bytes");
code_bytes.log(Obj.getData().size());
......@@ -165,17 +168,15 @@ class RegistryEventListener : public llvm::JITEventListener {
if (name == ".text")
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);
}
}
};
GlobalState::GlobalState() : context(llvm::getGlobalContext()) {
};
GlobalState::GlobalState() : context(llvm::getGlobalContext()) {};
llvm::JITEventListener* makeRegistryListener() {
return new RegistryEventListener();
}
}
......@@ -36,23 +36,22 @@ namespace pyston {
class PystonJITEventListener;
class FunctionAddressRegistry {
private:
private:
struct FuncInfo {
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) {
}
llvm::Function* llvm_func;
FuncInfo(const std::string& name, int length, llvm::Function* llvm_func)
: name(name), length(length), llvm_func(llvm_func) {}
};
typedef std::unordered_map<void*, FuncInfo> FuncMap;
FuncMap functions;
std::unordered_set<void*> lookup_neg_cache;
public:
std::string getFuncNameAtAddress(void* addr, bool demangle, bool *out_success=NULL);
public:
std::string getFuncNameAtAddress(void* addr, bool demangle, bool* out_success = NULL);
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();
};
......@@ -60,22 +59,22 @@ llvm::JITEventListener* makeRegistryListener();
llvm::JITEventListener* makeTracebacksListener();
struct GlobalState {
llvm::LLVMContext &context;
llvm::Module *stdlib_module, *cur_module;
llvm::TargetMachine *tm;
llvm::ExecutionEngine *engine;
llvm::LLVMContext& context;
llvm::Module* stdlib_module, *cur_module;
llvm::TargetMachine* tm;
llvm::ExecutionEngine* engine;
std::vector<llvm::JITEventListener*> jit_listeners;
FunctionAddressRegistry func_addr_registry;
llvm::Type *llvm_value_type, *llvm_value_type_ptr;
llvm::Type *llvm_class_type, *llvm_class_type_ptr;
llvm::Type *llvm_flavor_type, *llvm_flavor_type_ptr;
llvm::Type *llvm_opaque_type;
llvm::Type *llvm_str_type_ptr;
llvm::Type *llvm_clfunction_type_ptr;
llvm::Type *llvm_module_type_ptr, *llvm_bool_type_ptr;
llvm::Type *i1, *i8, *i8_ptr, *i32, *i64, *void_, *double_;
llvm::Type* llvm_value_type, *llvm_value_type_ptr;
llvm::Type* llvm_class_type, *llvm_class_type_ptr;
llvm::Type* llvm_flavor_type, *llvm_flavor_type_ptr;
llvm::Type* llvm_opaque_type;
llvm::Type* llvm_str_type_ptr;
llvm::Type* llvm_clfunction_type_ptr;
llvm::Type* llvm_module_type_ptr, *llvm_bool_type_ptr;
llvm::Type* i1, *i8, *i8_ptr, *i32, *i64, *void_, *double_;
GlobalFuncs funcs;
......@@ -85,9 +84,7 @@ struct GlobalState {
extern GlobalState g;
// in runtime_hooks.cpp:
void initGlobalFuncs(GlobalState &g);
void initGlobalFuncs(GlobalState& g);
}
#endif
This diff is collapsed.
This diff is collapsed.
......@@ -46,47 +46,46 @@ PystonJITEventListener::PystonJITEventListener() {
llvm::InitializeNativeTargetDisassembler();
std::string err;
const llvm::Target *target = llvm::TargetRegistry::getClosestTargetForJIT(err);
const llvm::Target* target = llvm::TargetRegistry::getClosestTargetForJIT(err);
assert(target);
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::MCRegisterInfo *MRI = target->createMCRegInfo(triple);
const llvm::MCRegisterInfo* MRI = target->createMCRegInfo(triple);
assert(MRI);
const llvm::MCAsmInfo *MAI = target->createMCAsmInfo(*MRI, triple);
const llvm::MCAsmInfo* MAI = target->createMCAsmInfo(*MRI, triple);
assert(MAI);
const llvm::MCInstrInfo *MII = target->createMCInstrInfo();
const llvm::MCInstrInfo* MII = target->createMCInstrInfo();
assert(MII);
std::string FeaturesStr;
const llvm::MCSubtargetInfo *STI = target->createMCSubtargetInfo(triple, CPU, FeaturesStr);
const llvm::MCSubtargetInfo* STI = target->createMCSubtargetInfo(triple, CPU, FeaturesStr);
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->getObjectFileInfo());
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);
int AsmPrinterVariant = MAI->getAssemblerDialect(); // 0 is ATT, 1 is Intel
IP = target->createMCInstPrinter(AsmPrinterVariant,
*MAI, *MII, *MRI, *STI);
IP = target->createMCInstPrinter(AsmPrinterVariant, *MAI, *MII, *MRI, *STI);
assert(IP);
llvm::MCCodeEmitter *CE = target->createMCCodeEmitter(*MII, *MRI, *STI, *Ctx);
llvm::MCCodeEmitter* CE = target->createMCCodeEmitter(*MII, *MRI, *STI, *Ctx);
assert(CE);
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);
streamer->InitSections();
streamer->SwitchSection(Ctx->getObjectFileInfo()->getTextSection());
......@@ -95,9 +94,10 @@ PystonJITEventListener::PystonJITEventListener() {
assert(asm_printer);
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());
......@@ -107,24 +107,23 @@ PystonJITEventListener::PystonJITEventListener() {
assert(MIA);
}
void PystonJITEventListener::NotifyFunctionEmitted(const llvm::Function &f,
void *ptr, size_t size,
const llvm::JITEvent_EmittedFunctionDetails &details) {
const llvm::MachineFunction &MF = *details.MF;//*const_cast<llvm::MachineFunction*>(details.MF);
void PystonJITEventListener::NotifyFunctionEmitted(const llvm::Function& f, void* ptr, size_t size,
const llvm::JITEvent_EmittedFunctionDetails& details) {
const llvm::MachineFunction& MF = *details.MF; //*const_cast<llvm::MachineFunction*>(details.MF);
printf("emitted! %p %ld %s\n", ptr, size, f.getName().data());
//MF.dump();
//MF.print(llvm::errs());
// MF.dump();
// MF.print(llvm::errs());
asm_printer->MF = &MF;
for (llvm::MachineFunction::const_iterator it = MF.begin(); it != MF.end(); it++) {
//it->dump();
// it->dump();
asm_printer->EmitBasicBlockStart(it);
for (llvm::MachineBasicBlock::const_instr_iterator it2 = it->instr_begin(); it2 != it->instr_end(); it2++) {
//llvm::errs() << "dump:";
//it2->print(llvm::errs());
// llvm::errs() << "dump:";
// it2->print(llvm::errs());
if (it2->getNumOperands() && (it2->getOperand(0).getType() == llvm::MachineOperand::MO_MCSymbol)) {
//it2->print(llvm::errs());
//it2->getOperand(0).print(llvm::errs());
// it2->print(llvm::errs());
// it2->getOperand(0).print(llvm::errs());
llvm::errs() << it2->getOperand(0).getMCSymbol()->getName() << '\n';
} else {
asm_printer->EmitInstruction(it2);
......@@ -135,7 +134,7 @@ void PystonJITEventListener::NotifyFunctionEmitted(const llvm::Function &f,
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::error_code code;
......@@ -147,10 +146,22 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
const char* type = "unknown";
bool b;
code = I->isText(b); assert(!code); if (b) 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";
code = I->isText(b);
assert(!code);
if (b)
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);
#if LLVMREV < 200442
......@@ -179,8 +190,8 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
#endif
}
llvm::MCObjectDisassembler *OD = new llvm::MCObjectDisassembler(*Obj.getObjectFile(), *DisAsm, *MIA);
llvm::MCModule *Mod = OD->buildModule(true);
llvm::MCObjectDisassembler* OD = new llvm::MCObjectDisassembler(*Obj.getObjectFile(), *DisAsm, *MIA);
llvm::MCModule* Mod = OD->buildModule(true);
// This is taken from llvm-objdump.cpp:
uint64_t text_start = 0;
......@@ -188,13 +199,13 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
llvm::outs() << "Atom " << (*AI)->getName() << ", starts at " << (void*)(*AI)->getBeginAddr() << ": \n";
if ((*AI)->getName() == ".text")
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) {
llvm::outs() << "0x";
llvm::outs().write_hex(II->Address);
//llvm::outs() << " (+0x";
//llvm::outs().write_hex(II->Address - text_start);
// llvm::outs() << " (+0x";
// llvm::outs().write_hex(II->Address - text_start);
llvm::outs() << " (+" << II->Address - text_start;
llvm::outs() << ") ";
......@@ -206,5 +217,4 @@ void PystonJITEventListener::NotifyObjectEmitted(const llvm::ObjectImage &Obj) {
llvm::outs().flush();
}
}
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.
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;
AST_Module* parse(const char* fn);
AST_Module* caching_parse(const char* fn);
}
#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