Commit b7e2863d authored by Hao Xu's avatar Hao Xu Committed by V8 LUCI CQ

use 64B loop header alignment in Turbofan on x64

Intel Optimization Manual update the suggestion for code alignment from 16B to 16B(for codes in legacy decoded pipeline) and 64B (for codes in Decoded Icache).

Since the loop often goes to the Decoded Icache, so align the loop header at 64B.

Change-Id: I1092e6dd5ea5937d5512865ce847ee00d1e8cb21
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3017311
Commit-Queue: Hao A Xu <hao.a.xu@intel.com>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Cr-Commit-Position: refs/heads/master@{#75807}
parent ff32d423
......@@ -401,6 +401,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void DataAlign(int m);
// Aligns code to something that's optimal for a jump target for the platform.
void CodeTargetAlign();
void LoopHeaderAlign() { CodeTargetAlign(); }
// Branch instructions
void b(int branch_offset, Condition cond = al,
......
......@@ -213,6 +213,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void DataAlign(int m);
// Aligns code to something that's optimal for a jump target for the platform.
void CodeTargetAlign();
void LoopHeaderAlign() { CodeTargetAlign(); }
inline void Unreachable();
......
......@@ -471,6 +471,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void Nop(int bytes = 1);
// Aligns code to something that's optimal for a jump target for the platform.
void CodeTargetAlign();
void LoopHeaderAlign() { CodeTargetAlign(); }
// Stack
void pushad();
......
......@@ -360,6 +360,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void DataAlign(int m);
// Aligns code to something that's optimal for a jump target for the platform.
void CodeTargetAlign();
void LoopHeaderAlign() { CodeTargetAlign(); }
// Different nop operations are used by the code generator to detect certain
// states of the generated code.
......
......@@ -359,6 +359,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void DataAlign(int m);
// Aligns code to something that's optimal for a jump target for the platform.
void CodeTargetAlign();
void LoopHeaderAlign() { CodeTargetAlign(); }
// Different nop operations are used by the code generator to detect certain
// states of the generated code.
......
......@@ -565,6 +565,7 @@ class Assembler : public AssemblerBase {
void DataAlign(int m);
// Aligns code to something that's optimal for a jump target for the platform.
void CodeTargetAlign();
void LoopHeaderAlign() { CodeTargetAlign(); }
// Branch instructions
void bclr(BOfield bo, int condition_bit, LKBit lk);
......
......@@ -364,6 +364,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void DataAlign(int m);
// Aligns code to something that's optimal for a jump target for the platform.
void CodeTargetAlign();
void LoopHeaderAlign() { CodeTargetAlign(); }
// Different nop operations are used by the code generator to detect certain
// states of the generated code.
......
......@@ -1055,6 +1055,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void DataAlign(int m);
// Aligns code to something that's optimal for a jump target for the platform.
void CodeTargetAlign();
void LoopHeaderAlign() { CodeTargetAlign(); }
void breakpoint(bool do_print) {
if (do_print) {
......
......@@ -443,6 +443,10 @@ void Assembler::CodeTargetAlign() {
Align(16); // Preferred alignment of jump targets on x64.
}
void Assembler::LoopHeaderAlign() {
Align(64); // Preferred alignment of loop header on x64.
}
bool Assembler::IsNop(Address addr) {
byte* a = reinterpret_cast<byte*>(addr);
while (*a == 0x66) a++;
......
......@@ -551,6 +551,7 @@ class V8_EXPORT_PRIVATE Assembler : public AssemblerBase {
void Nop(int bytes = 1);
// Aligns code to something that's optimal for a jump target for the platform.
void CodeTargetAlign();
void LoopHeaderAlign();
// Stack
void pushfq();
......
......@@ -320,8 +320,12 @@ void CodeGenerator::AssembleCode() {
offsets_info_.blocks_start = tasm()->pc_offset();
for (const InstructionBlock* block : instructions()->ao_blocks()) {
// Align loop headers on vendor recommended boundaries.
if (block->ShouldAlign() && !tasm()->jump_optimization_info()) {
tasm()->CodeTargetAlign();
if (!tasm()->jump_optimization_info()) {
if (block->ShouldAlignLoopHeader()) {
tasm()->LoopHeaderAlign();
} else if (block->ShouldAlignCodeTarget()) {
tasm()->CodeTargetAlign();
}
}
if (info->trace_turbo_json()) {
block_starts_[block->rpo_number().ToInt()] = tasm()->pc_offset();
......
......@@ -607,7 +607,8 @@ InstructionBlock::InstructionBlock(Zone* zone, RpoNumber rpo_number,
deferred_(deferred),
handler_(handler),
switch_target_(false),
alignment_(false),
code_target_alignment_(false),
loop_header_alignment_(false),
needs_frame_(false),
must_construct_frame_(false),
must_deconstruct_frame_(false) {}
......@@ -802,14 +803,14 @@ void InstructionSequence::ComputeAssemblyOrder() {
ao_blocks_->push_back(loop_end);
// This block will be the new machine-level loop header, so align
// this block instead of the loop header block.
loop_end->set_alignment(true);
loop_end->set_loop_header_alignment(true);
header_align = false;
}
}
block->set_alignment(header_align);
block->set_loop_header_alignment(header_align);
}
if (block->loop_header().IsValid() && block->IsSwitchTarget()) {
block->set_alignment(true);
block->set_code_target_alignment(true);
}
block->set_ao_number(RpoNumber::FromInt(ao++));
ao_blocks_->push_back(block);
......
......@@ -1537,7 +1537,8 @@ class V8_EXPORT_PRIVATE InstructionBlock final
}
inline bool IsLoopHeader() const { return loop_end_.IsValid(); }
inline bool IsSwitchTarget() const { return switch_target_; }
inline bool ShouldAlign() const { return alignment_; }
inline bool ShouldAlignCodeTarget() const { return code_target_alignment_; }
inline bool ShouldAlignLoopHeader() const { return loop_header_alignment_; }
using Predecessors = ZoneVector<RpoNumber>;
Predecessors& predecessors() { return predecessors_; }
......@@ -1560,7 +1561,8 @@ class V8_EXPORT_PRIVATE InstructionBlock final
void set_ao_number(RpoNumber ao_number) { ao_number_ = ao_number; }
void set_alignment(bool val) { alignment_ = val; }
void set_code_target_alignment(bool val) { code_target_alignment_ = val; }
void set_loop_header_alignment(bool val) { loop_header_alignment_ = val; }
void set_switch_target(bool val) { switch_target_ = val; }
......@@ -1588,7 +1590,10 @@ class V8_EXPORT_PRIVATE InstructionBlock final
const bool deferred_ : 1; // Block contains deferred code.
bool handler_ : 1; // Block is a handler entry point.
bool switch_target_ : 1;
bool alignment_ : 1; // insert alignment before this block
bool code_target_alignment_ : 1; // insert code target alignment before this
// block
bool loop_header_alignment_ : 1; // insert loop header alignment before this
// block
bool needs_frame_ : 1;
bool must_construct_frame_ : 1;
bool must_deconstruct_frame_ : 1;
......
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