[PATCH] D46326: ThinLTO+CFI: short-circuit direct calls to jump table entries

Dmitry Mikulin via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 1 11:34:21 PDT 2018


dmikulin created this revision.
dmikulin added reviewers: pcc, vlad.tsyrklevich, tejohnson.
Herald added subscribers: hiraditya, inglorion, mehdi_amini.

In ThinLTO+CFI direct function calls may go through jump table entries to reach the target. Since these calls don't require type checks, we can short-circuit them to their real targets.


https://reviews.llvm.org/D46326

Files:
  llvm/include/llvm/IR/Value.h
  llvm/lib/IR/Value.cpp
  llvm/lib/Transforms/IPO/LowerTypeTests.cpp


Index: llvm/lib/Transforms/IPO/LowerTypeTests.cpp
===================================================================
--- llvm/lib/Transforms/IPO/LowerTypeTests.cpp
+++ llvm/lib/Transforms/IPO/LowerTypeTests.cpp
@@ -963,15 +963,18 @@
 void LowerTypeTestsModule::importFunction(Function *F, bool isDefinition) {
   assert(F->getType()->getAddressSpace() == 0);
 
-  // Declaration of a local function - nothing to do.
-  if (F->isDeclarationForLinker() && isDefinition)
-    return;
-
   GlobalValue::VisibilityTypes Visibility = F->getVisibility();
   std::string Name = F->getName();
   Function *FDecl;
 
-  if (F->isDeclarationForLinker() && !isDefinition) {
+  if (F->isDeclarationForLinker() && isDefinition) {
+    FDecl = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
+                             Name + ".cfi", &M);
+    FDecl->setVisibility(Visibility);
+    F->replaceDirectCalls(FDecl);
+    return;
+  }
+  else if (F->isDeclarationForLinker() && !isDefinition) {
     // Declaration of an external function.
     FDecl = Function::Create(F->getFunctionType(), GlobalValue::ExternalLinkage,
                              Name + ".cfi_jt", &M);
Index: llvm/lib/IR/Value.cpp
===================================================================
--- llvm/lib/IR/Value.cpp
+++ llvm/lib/IR/Value.cpp
@@ -494,6 +494,19 @@
     C->handleOperandChange(this, New);
 }
 
+void Value::replaceDirectCalls(Value *New) {
+  use_iterator UI = use_begin(), E = use_end();
+  for (; UI != E;) {
+    Use &U = *UI;
+    ++UI;
+
+    auto *Usr = dyn_cast<CallInst>(U.getUser());
+    if (!Usr || !Usr->getCalledFunction())
+      continue;
+    U.set(New);
+  }
+}
+
 namespace {
 // Various metrics for how much to strip off of pointers.
 enum PointerStripKind {
Index: llvm/include/llvm/IR/Value.h
===================================================================
--- llvm/include/llvm/IR/Value.h
+++ llvm/include/llvm/IR/Value.h
@@ -305,6 +305,10 @@
   /// Unlike replaceAllUsesWith this function skips blockaddr uses.
   void replaceUsesExceptBlockAddr(Value *New);
 
+  /// replaceDirectCalls - Go through the uses list for this definition and
+  /// make each use, which is a direct function call.
+  void replaceDirectCalls(Value *New);
+
   //----------------------------------------------------------------------
   // Methods for handling the chain of uses of this Value.
   //


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D46326.144756.patch
Type: text/x-patch
Size: 2405 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180501/2159dd0d/attachment.bin>


More information about the llvm-commits mailing list