[llvm-branch-commits] [clang] b663278 - [OpenMP] Initial parsing/sema for the 'omp loop' construct
Author: Mike Rice Date: 2021-10-28T07:44:27-07:00 New Revision: b663278e084c9fff51275a670631784d3b9f730f URL: https://github.com/llvm/llvm-project/commit/b663278e084c9fff51275a670631784d3b9f730f DIFF: https://github.com/llvm/llvm-project/commit/b663278e084c9fff51275a670631784d3b9f730f.diff LOG: [OpenMP] Initial parsing/sema for the 'omp loop' construct Adds basic parsing/sema/serialization support for the #pragma omp loop directive. Differential Revision: https://reviews.llvm.org/D112499 Added: clang/test/OpenMP/generic_loop_ast_print.cpp clang/test/OpenMP/generic_loop_messages.cpp Modified: clang/include/clang-c/Index.h clang/include/clang/AST/RecursiveASTVisitor.h clang/include/clang/AST/StmtOpenMP.h clang/include/clang/Basic/DiagnosticSemaKinds.td clang/include/clang/Basic/OpenMPKinds.h clang/include/clang/Basic/StmtNodes.td clang/include/clang/Sema/Sema.h clang/include/clang/Serialization/ASTBitCodes.h clang/lib/AST/StmtOpenMP.cpp clang/lib/AST/StmtPrinter.cpp clang/lib/AST/StmtProfile.cpp clang/lib/Basic/OpenMPKinds.cpp clang/lib/CodeGen/CGStmt.cpp clang/lib/CodeGen/CGStmtOpenMP.cpp clang/lib/CodeGen/CodeGenFunction.h clang/lib/Parse/ParseOpenMP.cpp clang/lib/Sema/SemaExceptionSpec.cpp clang/lib/Sema/SemaOpenMP.cpp clang/lib/Sema/TreeTransform.h clang/lib/Serialization/ASTReaderStmt.cpp clang/lib/Serialization/ASTWriterStmt.cpp clang/lib/StaticAnalyzer/Core/ExprEngine.cpp clang/tools/libclang/CIndex.cpp clang/tools/libclang/CXCursor.cpp llvm/include/llvm/Frontend/OpenMP/OMP.td Removed: diff --git a/clang/include/clang-c/Index.h b/clang/include/clang-c/Index.h index b49acf6b58543..b0d7ef509c26f 100644 --- a/clang/include/clang-c/Index.h +++ b/clang/include/clang-c/Index.h @@ -2596,7 +2596,11 @@ enum CXCursorKind { */ CXCursor_OMPMetaDirective = 294, - CXCursor_LastStmt = CXCursor_OMPMetaDirective, + /** OpenMP loop directive. + */ + CXCursor_OMPGenericLoopDirective = 295, + + CXCursor_LastStmt = CXCursor_OMPGenericLoopDirective, /** * Cursor that represents the translation unit itself. diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index f200cd3920e67..74c49546c00bc 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -3023,6 +3023,9 @@ DEF_TRAVERSE_STMT(OMPDispatchDirective, DEF_TRAVERSE_STMT(OMPMaskedDirective, { TRY_TO(TraverseOMPExecutableDirective(S)); }) +DEF_TRAVERSE_STMT(OMPGenericLoopDirective, + { TRY_TO(TraverseOMPExecutableDirective(S)); }) + // OpenMP clauses. template bool RecursiveASTVisitor::TraverseOMPClause(OMPClause *C) { diff --git a/clang/include/clang/AST/StmtOpenMP.h b/clang/include/clang/AST/StmtOpenMP.h index 60d47b93ba79f..48b2dce152a64 100644 --- a/clang/include/clang/AST/StmtOpenMP.h +++ b/clang/include/clang/AST/StmtOpenMP.h @@ -1144,7 +1144,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { if (isOpenMPLoopBoundSharingDirective(Kind)) return CombinedDistributeEnd; if (isOpenMPWorksharingDirective(Kind) || isOpenMPTaskLoopDirective(Kind) || -isOpenMPDistributeDirective(Kind)) +isOpenMPGenericLoopDirective(Kind) || isOpenMPDistributeDirective(Kind)) return WorksharingEnd; return DefaultEnd; } @@ -1176,6 +1176,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { } void setIsLastIterVariable(Expr *IL) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || +isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1183,6 +1184,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { } void setLowerBoundVariable(Expr *LB) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || +isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1190,6 +1192,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { } void setUpperBoundVariable(Expr *UB) { assert((isOpenMPWorksharingDirective(getDirectiveKind()) || +isOpenMPGenericLoopDirective(getDirectiveKind()) || isOpenMPTaskLoopDirective(getDirectiveKind()) || isOpenMPDistributeDirective(getDirectiveKind())) && "expected worksharing loop directive"); @@ -1197,6 +1200,7 @@ class OMPLoopDirective : public OMPLoopBasedDirective { } void setStrideVariable(Expr *ST) { assert((isOpenMPWorksharing
[llvm-branch-commits] [llvm] 4db1cf5 - X86InstrInfo: Optimize more combinations of SUB+CMP
Author: Matthias Braun Date: 2021-10-28T10:23:28-07:00 New Revision: 4db1cf53740a8770b51ac1c03e8e9cc5e66eb83d URL: https://github.com/llvm/llvm-project/commit/4db1cf53740a8770b51ac1c03e8e9cc5e66eb83d DIFF: https://github.com/llvm/llvm-project/commit/4db1cf53740a8770b51ac1c03e8e9cc5e66eb83d.diff LOG: X86InstrInfo: Optimize more combinations of SUB+CMP `X86InstrInfo::optimizeCompareInstr` would only optimize a `SUB` followed by a `CMP` in `isRedundantFlagInstr`. This extends the code to also look for other combinations like `CMP`+`CMP`, `TEST`+`TEST`, `SUB x,0`+`TEST`. - Change `isRedundantFlagInstr` to run `analyzeCompareInstr` on the candidate instruction and compare the results. This normalizes things and gives consistent results for various comparisons (`CMP x, y`, `SUB x, y`) and immediate cases (`TEST x, x`, `SUB x, 0`, `CMP x, 0`...). - Turn `isRedundantFlagInstr` into a member function so it can call `analyzeCompare`. - We now also check `isRedundantFlagInstr` even if `IsCmpZero` is true, since we now have cases like `TEST`+`TEST`. Differential Revision: https://reviews.llvm.org/D110865 Added: Modified: llvm/lib/Target/X86/X86InstrInfo.cpp llvm/lib/Target/X86/X86InstrInfo.h llvm/test/CodeGen/X86/2007-02-16-BranchFold.ll llvm/test/CodeGen/X86/optimize-compare.mir llvm/test/CodeGen/X86/postalloc-coalescing.ll Removed: diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 96180e2b2bf2..81e7184fa07a 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -4011,42 +4011,72 @@ bool X86InstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg, return false; } -/// Check whether the first instruction, whose only -/// purpose is to update flags, can be made redundant. -/// CMPrr can be made redundant by SUBrr if the operands are the same. -/// This function can be extended later on. -/// SrcReg, SrcRegs: register operands for FlagI. -/// ImmValue: immediate for FlagI if it takes an immediate. -inline static bool isRedundantFlagInstr(const MachineInstr &FlagI, +bool X86InstrInfo::isRedundantFlagInstr(const MachineInstr &FlagI, Register SrcReg, Register SrcReg2, int64_t ImmMask, int64_t ImmValue, -const MachineInstr &OI) { - if (((FlagI.getOpcode() == X86::CMP64rr && OI.getOpcode() == X86::SUB64rr) || - (FlagI.getOpcode() == X86::CMP32rr && OI.getOpcode() == X86::SUB32rr) || - (FlagI.getOpcode() == X86::CMP16rr && OI.getOpcode() == X86::SUB16rr) || - (FlagI.getOpcode() == X86::CMP8rr && OI.getOpcode() == X86::SUB8rr)) && - ((OI.getOperand(1).getReg() == SrcReg && -OI.getOperand(2).getReg() == SrcReg2) || - (OI.getOperand(1).getReg() == SrcReg2 && -OI.getOperand(2).getReg() == SrcReg))) -return true; - - if (ImmMask != 0 && - ((FlagI.getOpcode() == X86::CMP64ri32 && -OI.getOpcode() == X86::SUB64ri32) || - (FlagI.getOpcode() == X86::CMP64ri8 && -OI.getOpcode() == X86::SUB64ri8) || - (FlagI.getOpcode() == X86::CMP32ri && OI.getOpcode() == X86::SUB32ri) || - (FlagI.getOpcode() == X86::CMP32ri8 && -OI.getOpcode() == X86::SUB32ri8) || - (FlagI.getOpcode() == X86::CMP16ri && OI.getOpcode() == X86::SUB16ri) || - (FlagI.getOpcode() == X86::CMP16ri8 && -OI.getOpcode() == X86::SUB16ri8) || - (FlagI.getOpcode() == X86::CMP8ri && OI.getOpcode() == X86::SUB8ri)) && - OI.getOperand(1).getReg() == SrcReg && - OI.getOperand(2).getImm() == ImmValue) -return true; - return false; +const MachineInstr &OI, +bool *IsSwapped) const { + switch (OI.getOpcode()) { + case X86::CMP64rr: + case X86::CMP32rr: + case X86::CMP16rr: + case X86::CMP8rr: + case X86::SUB64rr: + case X86::SUB32rr: + case X86::SUB16rr: + case X86::SUB8rr: { +Register OISrcReg; +Register OISrcReg2; +int64_t OIMask; +int64_t OIValue; +if (!analyzeCompare(OI, OISrcReg, OISrcReg2, OIMask, OIValue) || +OIMask != ImmMask || OIValue != ImmValue) + return false; +if (SrcReg == OISrcReg && SrcReg2 == OISrcReg2) { + *IsSwapped = false; + return true; +} +if (SrcReg == OISrcReg2 && SrcReg2 == OISrcReg) { + *IsSwapped = true; + return true; +} +return false; + } + case X86::CMP64ri32: + case X86::CMP64ri8: + case X86::CMP32ri: + case X86::CMP32ri8: + case X86::CMP16ri: + case X86::CMP16ri8: + case X86::CMP8ri: + case X86::SUB64ri32: + case X86::SUB64ri8: + case X86::SUB32ri: + case X86::SUB32ri8: + case X86::SUB16ri: + case X86::SUB16ri8: + case X86::SUB8ri: + case X86::TEST64rr: + case X86::TEST32rr: + case X
[llvm-branch-commits] [llvm] 26da34b - X86InstrInfo: Support immediates that are +1/-1 different in optimizeCompareInstr
Author: Matthias Braun Date: 2021-10-28T10:23:29-07:00 New Revision: 26da34b3238a018af23951b6a559f26aa78c9b6e URL: https://github.com/llvm/llvm-project/commit/26da34b3238a018af23951b6a559f26aa78c9b6e DIFF: https://github.com/llvm/llvm-project/commit/26da34b3238a018af23951b6a559f26aa78c9b6e.diff LOG: X86InstrInfo: Support immediates that are +1/-1 different in optimizeCompareInstr This extends `optimizeCompareInstr` to re-use previous comparison results if the previous comparison was with an immediate that was 1 bigger or smaller. Example: CMP x, 13 ... CMP x, 12 ; can be removed if we change the SETg SETg ...; x > 12 changed to `SETge` (x >= 13) removing CMP Motivation: This often happens because SelectionDAG canonicalization tends to add/subtract 1 often when optimizing for fallthrough blocks. Example for `x > C` the fallthrough optimization switches true/false blocks with `!(x > C)` --> `x <= C` and canonicalization turns this into `x < C + 1`. Differential Revision: https://reviews.llvm.org/D110867 Added: llvm/test/CodeGen/X86/peep-test-5.ll Modified: llvm/lib/Target/X86/X86InstrInfo.cpp llvm/lib/Target/X86/X86InstrInfo.h llvm/test/CodeGen/X86/optimize-compare.mir llvm/test/CodeGen/X86/use-cr-result-of-dom-icmp-st.ll Removed: diff --git a/llvm/lib/Target/X86/X86InstrInfo.cpp b/llvm/lib/Target/X86/X86InstrInfo.cpp index 81e7184fa07a..a9313bc8601a 100644 --- a/llvm/lib/Target/X86/X86InstrInfo.cpp +++ b/llvm/lib/Target/X86/X86InstrInfo.cpp @@ -4014,8 +4014,8 @@ bool X86InstrInfo::analyzeCompare(const MachineInstr &MI, Register &SrcReg, bool X86InstrInfo::isRedundantFlagInstr(const MachineInstr &FlagI, Register SrcReg, Register SrcReg2, int64_t ImmMask, int64_t ImmValue, -const MachineInstr &OI, -bool *IsSwapped) const { +const MachineInstr &OI, bool *IsSwapped, +int64_t *ImmDelta) const { switch (OI.getOpcode()) { case X86::CMP64rr: case X86::CMP32rr: @@ -4066,10 +4066,21 @@ bool X86InstrInfo::isRedundantFlagInstr(const MachineInstr &FlagI, int64_t OIMask; int64_t OIValue; if (analyzeCompare(OI, OISrcReg, OISrcReg2, OIMask, OIValue) && - SrcReg == OISrcReg && ImmMask == OIMask && OIValue == ImmValue) { -assert(SrcReg2 == X86::NoRegister && OISrcReg2 == X86::NoRegister && - "should not have 2nd register"); -return true; + SrcReg == OISrcReg && ImmMask == OIMask) { +if (OIValue == ImmValue) { + *ImmDelta = 0; + return true; +} else if (static_cast(ImmValue) == + static_cast(OIValue) - 1) { + *ImmDelta = -1; + return true; +} else if (static_cast(ImmValue) == + static_cast(OIValue) + 1) { + *ImmDelta = 1; + return true; +} else { + return false; +} } } return FlagI.isIdenticalTo(OI); @@ -4319,6 +4330,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, bool ShouldUpdateCC = false; bool IsSwapped = false; X86::CondCode NewCC = X86::COND_INVALID; + int64_t ImmDelta = 0; // Search backward from CmpInstr for the next instruction defining EFLAGS. const TargetRegisterInfo *TRI = &getRegisterInfo(); @@ -4365,7 +4377,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, // ... // EFLAGS not changed // cmp x, y // <-- can be removed if (isRedundantFlagInstr(CmpInstr, SrcReg, SrcReg2, CmpMask, CmpValue, - Inst, &IsSwapped)) { + Inst, &IsSwapped, &ImmDelta)) { Sub = &Inst; break; } @@ -4417,7 +4429,7 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, // EFLAGS is used by this instruction. X86::CondCode OldCC = X86::COND_INVALID; -if (MI || IsSwapped) { +if (MI || IsSwapped || ImmDelta != 0) { // We decode the condition code from opcode. if (Instr.isBranch()) OldCC = X86::getCondFromBranch(Instr); @@ -4470,9 +4482,59 @@ bool X86InstrInfo::optimizeCompareInstr(MachineInstr &CmpInstr, Register SrcReg, // We swap the condition code and synthesize the new opcode. ReplacementCC = getSwappedCondition(OldCC); if (ReplacementCC == X86::COND_INVALID) return false; + ShouldUpdateCC = true; +} else if (ImmDelta != 0) { + unsigned BitWidth = TRI->getRegSizeInBits(*MRI->getRegClass(SrcReg)); + // Shift amount for min/max constants to adjust for 8/16/32 instruction + // s