Skip to content

Commit

Permalink
Various fixes of method compiler, control graph and type analyzer
Browse files Browse the repository at this point in the history
Issue: #17
Issue: #92
  • Loading branch information
0x7CFE committed Jul 21, 2016
1 parent 3daecdb commit f17ef79
Show file tree
Hide file tree
Showing 6 changed files with 25 additions and 13 deletions.
2 changes: 1 addition & 1 deletion include/inference.h
Original file line number Diff line number Diff line change
Expand Up @@ -387,7 +387,7 @@ struct TContextStack {

class TypeSystem {
public:
TypeSystem(SmalltalkVM& vm) : m_vm(vm), m_lastContextIndex(0) {}
TypeSystem(SmalltalkVM& vm) : m_vm(vm), m_lastContextIndex(1) {}

typedef TSymbol* TSelector;

Expand Down
2 changes: 2 additions & 0 deletions include/types.h
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,8 @@ struct TInteger {
int32_t operator -(int32_t right) const { return getValue() - right; }
operator TObject*() const { return reinterpret_cast<TObject*>(m_value); }

void setRawValue(int32_t value) { m_value = value; }

private:
int32_t m_value;
protected:
Expand Down
4 changes: 4 additions & 0 deletions src/ControlGraph.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,9 +190,13 @@ void GraphConstructor::processNode(InstructionNode* node)
if (instruction.getArgument() == 0)
m_graph->getMeta().usesSelf = true;
ControlGraph::TMetaInfo::insertIndex(instruction.getArgument(), m_graph->getMeta().readsArguments);
m_currentDomain->pushValue(node);
break;

case opcode::pushInstance:
m_graph->getMeta().readsFields = true;
m_currentDomain->pushValue(node);
break;

case opcode::pushTemporary:
ControlGraph::TMetaInfo::insertIndex(instruction.getArgument(), m_graph->getMeta().readsTemporaries);
Expand Down
3 changes: 2 additions & 1 deletion src/JITRuntime.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,7 +226,7 @@ TBlock* JITRuntime::createBlock(TContext* callingContext, uint8_t argLocation, u

// NOTE This field is used by JIT VM to aid specialization lookup
// See MethodCompiler::getClosureMask() and lookupBlockFunctionInCache()
newBlock->stackTop = stackTop;
newBlock->stackTop.setRawValue(stackTop);

// Assigning creatingContext depending on the hierarchy
// Nested blocks inherit the outer creating context
Expand Down Expand Up @@ -557,6 +557,7 @@ void JITRuntime::updateBlockFunctionCache(TBlock* block, TBlockFunction function

// We have found a slot that may be used
fillBlockSlot(slot, block, function);
return;
}

// It seem that all slots are occupied by the friendly specializations.
Expand Down
24 changes: 13 additions & 11 deletions src/MethodCompiler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@ void createBlockTypes(

blockArguments.set(globals.arrayClass, type::Type::tkArray);

TObjectArray& temporaries = * block->creatingContext->temporaries;
TObjectArray& temporaries = * block->temporaries;
const uint32_t argumentLocation = block->argumentLocation;

const st::ControlGraph::TMetaInfo::TIndexList& readsTemporaries = blockGraph.getMeta().readsTemporaries;
Expand All @@ -943,14 +943,13 @@ void createBlockTypes(
TClass* const klass = isSmallInteger(argument) ? globals.smallIntClass : argument->getClass();
const type::Type newType(klass);

if (readsTemporaries[index] < argumentLocation)
if (readsTemporaries[index] < argumentLocation) {
closureTypes[tempIndex] = newType;
else
blockTemps.pushSubType(newType);

// We're interested only in temporaries from lexical context, not block arguments
if (readsTemporaries[index] < argumentLocation)
readIndices.pushSubType(type::Type(TInteger(readsTemporaries[index])));
readIndices.pushSubType(type::Type(TInteger(tempIndex)));
} else {
blockArguments.pushSubType(newType);
}
}

for (std::size_t index = 0; index < writesTemporaries.size(); index++) {
Expand Down Expand Up @@ -1308,10 +1307,13 @@ void MethodCompiler::doSendBinary(TJITContext& jit)
const type::Type& resultType = jit.inferContext[*jit.currentNode];

if (leftType.isLiteral() && rightType.isLiteral()) {
ConstantInt* const rawResult = jit.builder->getInt32(TInteger(resultType.getValue()));
Value* const result = jit.builder->CreateCall(m_baseFunctions.newInteger, rawResult);
setNodeValue(jit, jit.currentNode, result);
return;
// TODO Extend to all literals
if (isSmallInteger(resultType.getValue())) {
ConstantInt* const rawResult = jit.builder->getInt32(TInteger(resultType.getValue()));
Value* const result = jit.builder->CreateCall(m_baseFunctions.newInteger, rawResult);
setNodeValue(jit, jit.currentNode, result);
return;
}
}

// Literal int or (SmallInt) monotype
Expand Down
3 changes: 3 additions & 0 deletions src/TypeAnalyzer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ void TypeAnalyzer::run(const Type* blockType /*= 0*/) {

m_baseRun = true;
m_literalBranch = true;
m_tauLinker.reset();
m_tauLinker.run();
bool singleReturn = basicRun();

Expand Down Expand Up @@ -564,6 +565,8 @@ void TypeAnalyzer::doPushTemporary(const InstructionNode& instruction) {
InferContext::TVariableMap& closureTypes = methodContext->getBlockClosures()[captureIndex];

m_context[instruction] = closureTypes[tempIndex];
} else {
std::cout << "Could not find method context for block " << m_blockType->toString() << std::endl;
}
}
} else {
Expand Down

0 comments on commit f17ef79

Please sign in to comment.