[llvm] r335006 - [WebAssembly] Add more utility functions
Heejin Ahn via llvm-commits
llvm-commits at lists.llvm.org
Mon Jun 18 17:32:03 PDT 2018
Author: aheejin
Date: Mon Jun 18 17:32:03 2018
New Revision: 335006
URL: http://llvm.org/viewvc/llvm-project?rev=335006&view=rev
Log:
[WebAssembly] Add more utility functions
Summary:
Added more utility functions that will be used in EH-related passes Also
changed `LoopBottom` function to `getBottom` and uses templates to be
able to handle other classes as well, which will be used in CFGSort
later.
Reviewers: dschuff
Subscribers: sbc100, jgravelle-google, sunfish, llvm-commits
Differential Revision: https://reviews.llvm.org/D48262
Modified:
llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp
llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
llvm/trunk/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
llvm/trunk/lib/Target/WebAssembly/WebAssemblyUtilities.h
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp?rev=335006&r1=335005&r2=335006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGSort.cpp Mon Jun 18 17:32:03 2018
@@ -253,7 +253,7 @@ static void SortBlocks(MachineFunction &
assert(OnStack.count(MLI.getLoopFor(&MBB)) &&
"Blocks must be nested in their loops");
}
- while (OnStack.size() > 1 && &MBB == LoopBottom(OnStack.back()))
+ while (OnStack.size() > 1 && &MBB == WebAssembly::getBottom(OnStack.back()))
OnStack.pop_back();
}
assert(OnStack.pop_back_val() == nullptr &&
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp?rev=335006&r1=335005&r2=335006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyCFGStackify.cpp Mon Jun 18 17:32:03 2018
@@ -127,7 +127,8 @@ static void PlaceBlockMarker(
// Decide where in Header to put the BLOCK.
MachineBasicBlock::iterator InsertPos;
MachineLoop *HeaderLoop = MLI.getLoopFor(Header);
- if (HeaderLoop && MBB.getNumber() > LoopBottom(HeaderLoop)->getNumber()) {
+ if (HeaderLoop &&
+ MBB.getNumber() > WebAssembly::getBottom(HeaderLoop)->getNumber()) {
// Header is the header of a loop that does not lexically contain MBB, so
// the BLOCK needs to be above the LOOP, after any END constructs.
InsertPos = Header->begin();
@@ -181,7 +182,7 @@ static void PlaceLoopMarker(
// The operand of a LOOP is the first block after the loop. If the loop is the
// bottom of the function, insert a dummy block at the end.
- MachineBasicBlock *Bottom = LoopBottom(Loop);
+ MachineBasicBlock *Bottom = WebAssembly::getBottom(Loop);
auto Iter = std::next(MachineFunction::iterator(Bottom));
if (Iter == MF.end()) {
MachineBasicBlock *Label = MF.CreateMachineBasicBlock();
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyUtilities.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyUtilities.cpp?rev=335006&r1=335005&r2=335006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyUtilities.cpp (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyUtilities.cpp Mon Jun 18 17:32:03 2018
@@ -18,6 +18,13 @@
#include "llvm/CodeGen/MachineLoopInfo.h"
using namespace llvm;
+const char *const WebAssembly::ClangCallTerminateFn = "__clang_call_terminate";
+const char *const WebAssembly::CxaBeginCatchFn = "__cxa_begin_catch";
+const char *const WebAssembly::CxaRethrowFn = "__cxa_rethrow";
+const char *const WebAssembly::StdTerminateFn = "_ZSt9terminatev";
+const char *const WebAssembly::PersonalityWrapperFn =
+ "_Unwind_Wasm_CallPersonality";
+
bool WebAssembly::isArgument(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::ARGUMENT_I32:
@@ -71,6 +78,24 @@ bool WebAssembly::isChild(const MachineI
MFI.isVRegStackified(Reg);
}
+bool WebAssembly::isCallDirect(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case WebAssembly::CALL_VOID:
+ case WebAssembly::CALL_I32:
+ case WebAssembly::CALL_I64:
+ case WebAssembly::CALL_F32:
+ case WebAssembly::CALL_F64:
+ case WebAssembly::CALL_v16i8:
+ case WebAssembly::CALL_v8i16:
+ case WebAssembly::CALL_v4i32:
+ case WebAssembly::CALL_v4f32:
+ case WebAssembly::CALL_EXCEPT_REF:
+ return true;
+ default:
+ return false;
+ }
+}
+
bool WebAssembly::isCallIndirect(const MachineInstr &MI) {
switch (MI.getOpcode()) {
case WebAssembly::CALL_INDIRECT_VOID:
@@ -82,16 +107,136 @@ bool WebAssembly::isCallIndirect(const M
case WebAssembly::CALL_INDIRECT_v8i16:
case WebAssembly::CALL_INDIRECT_v4i32:
case WebAssembly::CALL_INDIRECT_v4f32:
+ case WebAssembly::CALL_INDIRECT_EXCEPT_REF:
+ return true;
+ default:
+ return false;
+ }
+}
+
+unsigned WebAssembly::getCalleeOpNo(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case WebAssembly::CALL_VOID:
+ case WebAssembly::CALL_INDIRECT_VOID:
+ return 0;
+ case WebAssembly::CALL_I32:
+ case WebAssembly::CALL_I64:
+ case WebAssembly::CALL_F32:
+ case WebAssembly::CALL_F64:
+ case WebAssembly::CALL_EXCEPT_REF:
+ case WebAssembly::CALL_INDIRECT_I32:
+ case WebAssembly::CALL_INDIRECT_I64:
+ case WebAssembly::CALL_INDIRECT_F32:
+ case WebAssembly::CALL_INDIRECT_F64:
+ case WebAssembly::CALL_INDIRECT_EXCEPT_REF:
+ return 1;
+ default:
+ llvm_unreachable("Not a call instruction");
+ }
+}
+
+bool WebAssembly::isMarker(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case WebAssembly::BLOCK:
+ case WebAssembly::END_BLOCK:
+ case WebAssembly::LOOP:
+ case WebAssembly::END_LOOP:
+ case WebAssembly::TRY:
+ case WebAssembly::END_TRY:
return true;
default:
return false;
}
}
-MachineBasicBlock *llvm::LoopBottom(const MachineLoop *Loop) {
- MachineBasicBlock *Bottom = Loop->getHeader();
- for (MachineBasicBlock *MBB : Loop->blocks())
- if (MBB->getNumber() > Bottom->getNumber())
- Bottom = MBB;
- return Bottom;
+bool WebAssembly::isThrow(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case WebAssembly::THROW_I32:
+ case WebAssembly::THROW_I64:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool WebAssembly::isRethrow(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case WebAssembly::RETHROW:
+ case WebAssembly::RETHROW_TO_CALLER:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool WebAssembly::isCatch(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case WebAssembly::CATCH_I32:
+ case WebAssembly::CATCH_I64:
+ case WebAssembly::CATCH_ALL:
+ return true;
+ default:
+ return false;
+ }
+}
+
+bool WebAssembly::mayThrow(const MachineInstr &MI) {
+ switch (MI.getOpcode()) {
+ case WebAssembly::THROW_I32:
+ case WebAssembly::THROW_I64:
+ case WebAssembly::RETHROW:
+ return true;
+ }
+ if (isCallIndirect(MI))
+ return true;
+ if (!MI.isCall())
+ return false;
+
+ const MachineOperand &MO = MI.getOperand(getCalleeOpNo(MI));
+ assert(MO.isGlobal());
+ const auto *F = dyn_cast<Function>(MO.getGlobal());
+ if (!F)
+ return true;
+ if (F->doesNotThrow())
+ return false;
+ // These functions never throw
+ if (F->getName() == CxaBeginCatchFn || F->getName() == PersonalityWrapperFn ||
+ F->getName() == ClangCallTerminateFn || F->getName() == StdTerminateFn)
+ return false;
+ return true;
+}
+
+bool WebAssembly::isCatchTerminatePad(const MachineBasicBlock &MBB) {
+ if (!MBB.isEHPad())
+ return false;
+ bool SeenCatch = false;
+ for (auto &MI : MBB) {
+ if (MI.getOpcode() == WebAssembly::CATCH_I32 ||
+ MI.getOpcode() == WebAssembly::CATCH_I64)
+ SeenCatch = true;
+ if (SeenCatch && MI.isCall()) {
+ const MachineOperand &CalleeOp = MI.getOperand(getCalleeOpNo(MI));
+ if (CalleeOp.isGlobal() &&
+ CalleeOp.getGlobal()->getName() == ClangCallTerminateFn)
+ return true;
+ }
+ }
+ return false;
+}
+
+bool WebAssembly::isCatchAllTerminatePad(const MachineBasicBlock &MBB) {
+ if (!MBB.isEHPad())
+ return false;
+ bool SeenCatchAll = false;
+ for (auto &MI : MBB) {
+ if (MI.getOpcode() == WebAssembly::CATCH_ALL)
+ SeenCatchAll = true;
+ if (SeenCatchAll && MI.isCall()) {
+ const MachineOperand &CalleeOp = MI.getOperand(getCalleeOpNo(MI));
+ if (CalleeOp.isGlobal() &&
+ CalleeOp.getGlobal()->getName() == StdTerminateFn)
+ return true;
+ }
+ }
+ return false;
}
Modified: llvm/trunk/lib/Target/WebAssembly/WebAssemblyUtilities.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Target/WebAssembly/WebAssemblyUtilities.h?rev=335006&r1=335005&r2=335006&view=diff
==============================================================================
--- llvm/trunk/lib/Target/WebAssembly/WebAssemblyUtilities.h (original)
+++ llvm/trunk/lib/Target/WebAssembly/WebAssemblyUtilities.h Mon Jun 18 17:32:03 2018
@@ -16,11 +16,10 @@
#ifndef LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYUTILITIES_H
#define LLVM_LIB_TARGET_WEBASSEMBLY_WEBASSEMBLYUTILITIES_H
+#include "llvm/CodeGen/MachineBasicBlock.h"
+
namespace llvm {
-class MachineBasicBlock;
-class MachineInstr;
-class MachineLoop;
class WebAssemblyFunctionInfo;
namespace WebAssembly {
@@ -29,15 +28,45 @@ bool isArgument(const MachineInstr &MI);
bool isCopy(const MachineInstr &MI);
bool isTee(const MachineInstr &MI);
bool isChild(const MachineInstr &MI, const WebAssemblyFunctionInfo &MFI);
+bool isCallDirect(const MachineInstr &MI);
bool isCallIndirect(const MachineInstr &MI);
+bool isMarker(const MachineInstr &MI);
+bool isThrow(const MachineInstr &MI);
+bool isRethrow(const MachineInstr &MI);
+bool isCatch(const MachineInstr &MI);
+bool mayThrow(const MachineInstr &MI);
+
+/// Returns the operand number of a callee, assuming the argument is a call
+/// instruction.
+unsigned getCalleeOpNo(const MachineInstr &MI);
+
+/// Returns if the given BB is a single BB terminate pad which starts with a
+/// 'catch' instruction.
+bool isCatchTerminatePad(const MachineBasicBlock &MBB);
+/// Returns if the given BB is a single BB terminate pad which starts with a
+/// 'catch_all' insrtruction.
+bool isCatchAllTerminatePad(const MachineBasicBlock &MBB);
+
+// Exception-related function names
+extern const char *const ClangCallTerminateFn;
+extern const char *const CxaBeginCatchFn;
+extern const char *const CxaRethrowFn;
+extern const char *const StdTerminateFn;
+extern const char *const PersonalityWrapperFn;
+
+/// Return the "bottom" block of an entity, which can be either a MachineLoop or
+/// WebAssemblyException. This differs from MachineLoop::getBottomBlock in that
+/// it works even if the entity is discontiguous.
+template <typename T> MachineBasicBlock *getBottom(const T *Unit) {
+ MachineBasicBlock *Bottom = Unit->getHeader();
+ for (MachineBasicBlock *MBB : Unit->blocks())
+ if (MBB->getNumber() > Bottom->getNumber())
+ Bottom = MBB;
+ return Bottom;
+}
} // end namespace WebAssembly
-/// Return the "bottom" block of a loop. This differs from
-/// MachineLoop::getBottomBlock in that it works even if the loop is
-/// discontiguous.
-MachineBasicBlock *LoopBottom(const MachineLoop *Loop);
-
} // end namespace llvm
#endif
More information about the llvm-commits
mailing list