Order jump tables for deterministic or randomized emission.
BUG=
R=stichnot@chromium.org, jvoung, stichnot
Review URL: https://codereview.chromium.org/1260183008.
diff --git a/src/IceGlobalContext.cpp b/src/IceGlobalContext.cpp
index 8bfc5dd..1bcb857 100644
--- a/src/IceGlobalContext.cpp
+++ b/src/IceGlobalContext.cpp
@@ -878,11 +878,32 @@
return getConstPool()->ExternRelocatables.getConstantPool();
}
+JumpTableDataList GlobalContext::getJumpTables() {
+ JumpTableDataList JumpTables(*getJumpTableList());
+ if (getFlags().shouldReorderPooledConstants()) {
+ // If reorder-pooled-constants option is set to true, we need to shuffle the
+ // constant pool before emitting it.
+ RandomShuffle(JumpTables.begin(), JumpTables.end(), [this](uint64_t N) {
+ return (uint32_t)getRNG().next(N);
+ });
+ } else {
+ // Make order deterministic by sorting into functions and then ID of the
+ // jump table within that function.
+ std::sort(JumpTables.begin(), JumpTables.end(), [](const JumpTableData &A,
+ const JumpTableData &B) {
+ if (A.getFunctionName() != B.getFunctionName())
+ return A.getFunctionName() < B.getFunctionName();
+ return A.getId() < B.getId();
+ });
+ }
+ return JumpTables;
+}
+
JumpTableData &GlobalContext::addJumpTable(IceString FuncName, SizeT Id,
SizeT NumTargets) {
- auto JumpTables = getJumpTables();
- JumpTables->emplace_back(FuncName, Id, NumTargets);
- return JumpTables->back();
+ auto JumpTableList = getJumpTableList();
+ JumpTableList->emplace_back(FuncName, Id, NumTargets);
+ return JumpTableList->back();
}
TimerStackIdT GlobalContext::newTimerStackID(const IceString &Name) {
diff --git a/src/IceGlobalContext.h b/src/IceGlobalContext.h
index acef4c5..7f27024 100644
--- a/src/IceGlobalContext.h
+++ b/src/IceGlobalContext.h
@@ -212,9 +212,7 @@
ConstantList getConstantExternSyms();
/// Return a locked pointer to the registered jump tables.
- LockedPtr<JumpTableDataList> getJumpTables() {
- return LockedPtr<JumpTableDataList>(&JumpTables, &JumpTablesLock);
- }
+ JumpTableDataList getJumpTables();
/// Create a new jump table entry and return a reference to it.
JumpTableData &addJumpTable(IceString FuncName, SizeT Id, SizeT NumTargets);
@@ -467,9 +465,9 @@
std::unique_ptr<ConstantPool> ConstPool;
ICE_CACHELINE_BOUNDARY;
- // Managed by getJumpTables()
+ // Managed by getJumpTableList()
GlobalLockType JumpTablesLock;
- JumpTableDataList JumpTables;
+ JumpTableDataList JumpTableList;
ICE_CACHELINE_BOUNDARY;
// Managed by getErrorStatus()
@@ -522,6 +520,9 @@
LockedPtr<ConstantPool> getConstPool() {
return LockedPtr<ConstantPool>(ConstPool.get(), &ConstPoolLock);
}
+ LockedPtr<JumpTableDataList> getJumpTableList() {
+ return LockedPtr<JumpTableDataList>(&JumpTableList, &JumpTablesLock);
+ }
LockedPtr<CodeStats> getStatsCumulative() {
return LockedPtr<CodeStats>(&StatsCumulative, &StatsLock);
}
diff --git a/src/IceSwitchLowering.h b/src/IceSwitchLowering.h
index 34c9373..57c7d3c 100644
--- a/src/IceSwitchLowering.h
+++ b/src/IceSwitchLowering.h
@@ -79,7 +79,6 @@
/// ELF section once the offsets from the start of the function are known.
class JumpTableData {
JumpTableData() = delete;
- JumpTableData(const JumpTableData &) = delete;
JumpTableData &operator=(const JumpTableData &) = delete;
public:
@@ -87,7 +86,9 @@
: FuncName(FuncName), Id(Id) {
TargetOffsets.reserve(NumTargets);
}
+ JumpTableData(const JumpTableData &) = default;
JumpTableData(JumpTableData &&) = default;
+ JumpTableData &operator=(JumpTableData &&) = default;
void pushTarget(intptr_t Offset) { TargetOffsets.emplace_back(Offset); }
@@ -98,8 +99,8 @@
}
private:
- const IceString FuncName;
- const SizeT Id;
+ IceString FuncName;
+ SizeT Id;
std::vector<intptr_t> TargetOffsets;
};
diff --git a/src/IceTargetLoweringX8632.cpp b/src/IceTargetLoweringX8632.cpp
index e8e89dd..a42e122 100644
--- a/src/IceTargetLoweringX8632.cpp
+++ b/src/IceTargetLoweringX8632.cpp
@@ -243,8 +243,8 @@
switch (Ctx->getFlags().getOutFileType()) {
case FT_Elf: {
ELFObjectWriter *Writer = Ctx->getObjectWriter();
- for (const JumpTableData &JumpTable : *Ctx->getJumpTables())
- Writer->writeJumpTable(JumpTable, llvm::ELF::R_386_32);
+ for (const JumpTableData &JT : Ctx->getJumpTables())
+ Writer->writeJumpTable(JT, llvm::ELF::R_386_32);
} break;
case FT_Asm:
// Already emitted from Cfg
@@ -253,7 +253,7 @@
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
- for (const JumpTableData &JT : *Ctx->getJumpTables()) {
+ for (const JumpTableData &JT : Ctx->getJumpTables()) {
Str << "\t.section\t.rodata." << JT.getFunctionName()
<< "$jumptable,\"a\",@progbits\n";
Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";
diff --git a/src/IceTargetLoweringX8664.cpp b/src/IceTargetLoweringX8664.cpp
index ed586a3..1fcf0b9 100644
--- a/src/IceTargetLoweringX8664.cpp
+++ b/src/IceTargetLoweringX8664.cpp
@@ -240,9 +240,9 @@
switch (Ctx->getFlags().getOutFileType()) {
case FT_Elf: {
ELFObjectWriter *Writer = Ctx->getObjectWriter();
- for (const JumpTableData &JumpTable : *Ctx->getJumpTables())
+ for (const JumpTableData &JT : Ctx->getJumpTables())
// TODO(jpp): not 386.
- Writer->writeJumpTable(JumpTable, llvm::ELF::R_386_32);
+ Writer->writeJumpTable(JT, llvm::ELF::R_386_32);
} break;
case FT_Asm:
// Already emitted from Cfg
@@ -251,7 +251,7 @@
if (!BuildDefs::dump())
return;
Ostream &Str = Ctx->getStrEmit();
- for (const JumpTableData &JT : *Ctx->getJumpTables()) {
+ for (const JumpTableData &JT : Ctx->getJumpTables()) {
Str << "\t.section\t.rodata." << JT.getFunctionName()
<< "$jumptable,\"a\",@progbits\n";
Str << "\t.align\t" << typeWidthInBytes(getPointerType()) << "\n";