Skip to content

Commit

Permalink
[vm] Add LoadThreadInstr
Browse files Browse the repository at this point in the history
Introduces a new IL instruction to load the THR register as an untagged
value in IL.

Split off from https://dart-review.googlesource.com/c/sdk/+/229544.

TEST=runtime/vm/compiler/backend/il_test.cc vm/cc/IRTest_LoadThread

Bug: #47777

Change-Id: Ic6bf59b05c89593773dbc91d623cd0078657c8ab
Cq-Include-Trybots: luci.dart.try:vm-kernel-win-debug-x64-try,vm-kernel-linux-debug-ia32-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/235602
Reviewed-by: Slava Egorov <vegorov@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Daco Harkes <dacoharkes@google.com>
  • Loading branch information
dcharkes authored and Commit Bot committed Mar 11, 2022
1 parent 2a522a9 commit d70e97f
Show file tree
Hide file tree
Showing 4 changed files with 117 additions and 2 deletions.
4 changes: 4 additions & 0 deletions runtime/vm/compiler/backend/constant_propagator.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1454,6 +1454,10 @@ void ConstantPropagator::VisitBitCast(BitCastInstr* instr) {
SetValue(instr, non_constant_);
}

void ConstantPropagator::VisitLoadThread(LoadThreadInstr* instr) {
SetValue(instr, non_constant_);
}

void ConstantPropagator::VisitUnaryUint32Op(UnaryUint32OpInstr* instr) {
// TODO(kmillikin): Handle unary operations.
SetValue(instr, non_constant_);
Expand Down
8 changes: 6 additions & 2 deletions runtime/vm/compiler/backend/il.cc
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include "vm/compiler/backend/flow_graph_compiler.h"
#include "vm/compiler/backend/linearscan.h"
#include "vm/compiler/backend/locations.h"
#include "vm/compiler/backend/locations_helpers.h"
#include "vm/compiler/backend/loops.h"
#include "vm/compiler/backend/range_analysis.h"
#include "vm/compiler/ffi/frame_rebase.h"
Expand Down Expand Up @@ -6863,6 +6864,11 @@ Representation FfiCallInstr::representation() const {
return marshaller_.RepInFfiCall(compiler::ffi::kResultIndex);
}

// TODO(http://dartbug.com/48543): integrate with register allocator directly.
DEFINE_BACKEND(LoadThread, (Register out)) {
__ MoveRegister(out, THR);
}

// SIMD

SimdOpInstr::Kind SimdOpInstr::KindForOperator(MethodRecognizer::Kind kind) {
Expand Down Expand Up @@ -7038,12 +7044,10 @@ static const Representation kUnboxedInt8 = kUnboxedInt32;

// Define the metadata array.
static const SimdOpInfo simd_op_information[] = {
#define PP_APPLY(M, Args) M Args
#define CASE(Arity, Mask, Name, Args, Result) \
{Arity, HAS_##Mask, REP(Result), {PP_APPLY(ENCODE_INPUTS_##Arity, Args)}},
SIMD_OP_LIST(CASE, CASE)
#undef CASE
#undef PP_APPLY
};

// Undef all auxiliary macros.
Expand Down
27 changes: 27 additions & 0 deletions runtime/vm/compiler/backend/il.h
Original file line number Diff line number Diff line change
Expand Up @@ -512,6 +512,7 @@ struct InstrAttrs {
M(BoxSmallInt, kNoGC) \
M(IntConverter, kNoGC) \
M(BitCast, kNoGC) \
M(LoadThread, kNoGC) \
M(Deoptimize, kNoGC) \
M(SimdOp, kNoGC)

Expand Down Expand Up @@ -9279,6 +9280,32 @@ class BitCastInstr : public TemplateDefinition<1, NoThrow, Pure> {
DISALLOW_COPY_AND_ASSIGN(BitCastInstr);
};

class LoadThreadInstr : public TemplateDefinition<0, NoThrow, Pure> {
public:
LoadThreadInstr() : TemplateDefinition(DeoptId::kNone) {}

virtual bool ComputeCanDeoptimize() const { return false; }

virtual Representation representation() const { return kUntagged; }

virtual Representation RequiredInputRepresentation(intptr_t idx) const {
UNREACHABLE();
}

virtual CompileType ComputeType() const { return CompileType::Int(); }

// CSE is allowed. The thread should always be the same value.
virtual bool AttributesEqual(const Instruction& other) const {
ASSERT(other.IsLoadThread());
return true;
}

DECLARE_INSTRUCTION(LoadThread);

private:
DISALLOW_COPY_AND_ASSIGN(LoadThreadInstr);
};

// SimdOpInstr
//
// All SIMD intrinsics and recognized methods are represented via instances
Expand Down
80 changes: 80 additions & 0 deletions runtime/vm/compiler/backend/il_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -872,4 +872,84 @@ ISOLATE_UNIT_TEST_CASE(IRTest_RawLoadField) {
EXPECT_EQ(100, ptr2);
}

ISOLATE_UNIT_TEST_CASE(IRTest_LoadThread) {
// clang-format off
auto kScript = R"(
import 'dart:ffi';

int myFunction() {
return 100;
}

void anotherFunction() {}
)";
// clang-format on

const auto& root_library = Library::Handle(LoadTestScript(kScript));
Zone* const zone = Thread::Current()->zone();
auto& invoke_result = Instance::Handle(zone);
invoke_result ^= Invoke(root_library, "myFunction");
EXPECT_EQ(Smi::New(100), invoke_result.ptr());

const auto& my_function =
Function::Handle(GetFunction(root_library, "myFunction"));

TestPipeline pipeline(my_function, CompilerPass::kJIT);
FlowGraph* flow_graph = pipeline.RunPasses({
CompilerPass::kComputeSSA,
});

ReturnInstr* return_instr = nullptr;
{
ILMatcher cursor(flow_graph, flow_graph->graph_entry()->normal_entry());

EXPECT(cursor.TryMatch({
kMoveGlob,
{kMatchReturn, &return_instr},
}));
}

auto* const load_thread_instr = new (zone) LoadThreadInstr();
flow_graph->InsertBefore(return_instr, load_thread_instr, nullptr,
FlowGraph::kValue);
auto load_thread_value = Value(load_thread_instr);

auto* const convert_instr = new (zone) IntConverterInstr(
kUntagged, kUnboxedFfiIntPtr, &load_thread_value, DeoptId::kNone);
flow_graph->InsertBefore(return_instr, convert_instr, nullptr,
FlowGraph::kValue);
auto convert_value = Value(convert_instr);

auto* const box_instr = BoxInstr::Create(kUnboxedFfiIntPtr, &convert_value);
flow_graph->InsertBefore(return_instr, box_instr, nullptr, FlowGraph::kValue);

return_instr->InputAt(0)->definition()->ReplaceUsesWith(box_instr);

{
// Check we constructed the right graph.
ILMatcher cursor(flow_graph, flow_graph->graph_entry()->normal_entry());
EXPECT(cursor.TryMatch({
kMoveGlob,
kMatchAndMoveLoadThread,
kMatchAndMoveIntConverter,
kMatchAndMoveBox,
kMatchReturn,
}));
}

pipeline.RunForcedOptimizedAfterSSAPasses();

{
#if !defined(PRODUCT)
SetFlagScope<bool> sfs(&FLAG_disassemble_optimized, true);
#endif
pipeline.CompileGraphAndAttachFunction();
}

// Ensure we can successfully invoke the function.
invoke_result ^= Invoke(root_library, "myFunction");
intptr_t result_int = Integer::Cast(invoke_result).AsInt64Value();
EXPECT_EQ(reinterpret_cast<intptr_t>(thread), result_int);
}

} // namespace dart

0 comments on commit d70e97f

Please sign in to comment.