summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Target/ARM/ARMInstructionSelector.cpp
Commit message (Collapse)AuthorAgeFilesLines
...
* [GlobalISel] Make GlobalISel a non-optional library.Quentin Colombet2017-08-031-4/+0
| | | | | | | | With this change, the GlobalISel library gets always built. In particular, this is not possible to opt GlobalISel out of the build using the LLVM_BUILD_GLOBAL_ISEL variable any more. llvm-svn: 309990
* [ARM] GlobalISel: Select simple G_GLOBAL_VALUE instructionsDiana Picus2017-08-031-0/+57
| | | | | | | | | | | | | Add support in the instruction selector for G_GLOBAL_VALUE for ELF and MachO for the static relocation model. We don't handle Windows yet because that's Thumb-only, and we don't handle Thumb in general at the moment. Support for PIC, ROPI, RWPI and TLS will be added in subsequent commits. Differential Revision: https://reviews.llvm.org/D35883 llvm-svn: 309927
* Re-commit: r309094 [globalisel][tablegen] Fuse the generated tables together.Daniel Sanders2017-07-271-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Summary: Now that we have control flow in place, fuse the per-rule tables into a single table. This is a compile-time saving at this point. However, this will also enable the optimization of a table so that similar instructions can be tested together, reducing the time spent on the matching the code. This is NFC in terms of externally visible behaviour but some internals have changed slightly. State.MIs is no longer reset between each rule that is attempted because it's not necessary to do so. As a consequence of this the restriction on the order that instructions are added to State.MIs has been relaxed to only affect recorded instructions that require new elements to be added to the vector. GIM_RecordInsn can now write to any element from 1 to State.MIs.size() instead of just State.MIs.size(). The compile-time regressions from the last commit were caused by the ARM target including a non-const variable (zero_reg) in the table and therefore generating an initializer for it. That variable is now const. Reviewers: ab, t.p.northover, qcolombet, rovka, aditya_nandakumar Reviewed By: rovka Subscribers: kristof.beyls, igorb, llvm-commits Differential Revision: https://reviews.llvm.org/D35681 llvm-svn: 309264
* [ARM] GlobalISel: Support G_BRCONDDiana Picus2017-07-141-0/+23
| | | | | | | | | | | | Insert a TSTri to set the flags and a Bcc to branch based on their values. This is a bit inefficient in the (common) cases where the condition for the branch comes from a compare right before the branch, since we set the flags both as part of the compare lowering and as part of the branch lowering. We're going to live with that until we settle on a principled way to handle this kind of situation, which occurs with other patterns as well (combines might be the way forward here). llvm-svn: 308009
* [ARM] GlobalISel: Simplify inst selector code. NFCDiana Picus2017-07-121-198/+143
| | | | | | | | | | | Refactor CmpHelper into something simpler. It was overkill to use templates for this - instead, use a simple CmpConstants structure to hold the opcodes and other constants that are different when selecting int / float / double comparisons. Also, extract some of the helpers that were in CmpHelper into ARMInstructionSelector and make use of some of them when selecting other things than just compares. llvm-svn: 307766
* [ARM] GlobalISel: Select s64 G_FCMPDiana Picus2017-07-121-3/+38
| | | | | | | Very similar to how we select s32 G_FCMP, the only thing that is different is the exact opcodes that we use. llvm-svn: 307763
* [ARM] GlobalISel: Fixup r307365Diana Picus2017-07-071-11/+10
| | | | | | | Rename member DebugLoc -> DbgLoc (so it doesn't conflict with the class name). llvm-svn: 307366
* [ARM] GlobalISel: Select hard G_FCMP for s32Diana Picus2017-07-071-63/+234
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | We lower to a sequence consisting of: - MOVi 0 into a register - VCMPS to do the actual comparison and set the VFP flags - FMSTAT to move the flags out of the VFP unit - MOVCCi to either use the "zero register" that we have previously set with the MOVi, or move 1 into the result register, based on the values of the flags As was the case with soft-float, for some predicates (one, ueq) we actually need two comparisons instead of just one. When that happens, we generate two VCMPS-FMSTAT-MOVCCi sequences and chain them by means of using the result of the first MOVCCi as the "zero register" for the second one. This is a bit overkill, since one comparison followed by two non-flag-setting conditional moves should be enough. In any case, the backend manages to CSE one of the comparisons away so it doesn't matter much. Note that unlike SelectionDAG and FastISel, we always use VCMPS, and not VCMPES. This makes the code a lot simpler, and it also seems correct since the LLVM Lang Ref defines simple true/false returns if the operands are QNaN's. For SNaN's, even VCMPS throws an Invalid Operand exception, so they won't be slipping through unnoticed. Implementation-wise, this introduces a template so we can share the same code that we use for handling integer comparisons, since the only differences are in the details (exact opcodes to be used etc). Hopefully this will be easy to extend to s64 G_FCMP. llvm-svn: 307365
* [globalisel][tablegen] Partially fix compile-time regressions by converting ↵Daniel Sanders2017-07-041-0/+2
| | | | | | | | | | | | | | | | | | | | | | matcher to state-machine(s) Summary: Replace the matcher if-statements for each rule with a state-machine. This significantly reduces compile time, memory allocations, and cumulative memory allocation when compiling AArch64InstructionSelector.cpp.o after r303259 is recommitted. The following patches will expand on this further to fully fix the regressions. Reviewers: rovka, ab, t.p.northover, qcolombet, aditya_nandakumar Reviewed By: ab Subscribers: vitalybuka, aemerson, javed.absar, igorb, llvm-commits, kristof.beyls Differential Revision: https://reviews.llvm.org/D33758 llvm-svn: 307079
* [ARM] GlobalISel: Support G_SELECT for i32Diana Picus2017-06-271-0/+50
| | | | | | | | | | * Mark as legal for (s32, i1, s32, s32) * Map everything into GPRs * Select to two instructions: a CMP of the condition against 0, to set the flags, and a MOVCCr to select between the two inputs based on the flags that we've just set llvm-svn: 306382
* [ARM] GlobalISel: Support G_ICMP for i32 and pointersDiana Picus2017-06-191-0/+105
| | | | | | | | | | | | | | Add support throughout the pipeline: - mark as legal for s32 and pointers - map to GPRs - lower to a sequence of instructions, which moves 0 or 1 into the result register based on the flags set by a CMPrr We have copied from FastISel a helper function which maps CmpInst predicates into ARMCC codes. Ideally, we should be able to move it somewhere that both FastISel and GlobalISel can use. llvm-svn: 305672
* [ARM] GlobalISel: Purge G_SEQUENCEDiana Picus2017-06-071-36/+34
| | | | | | | | | | | | | | | | | According to the commit message from r296921, G_MERGE_VALUES and G_INSERT are to be preferred over G_SEQUENCE. Therefore, stop generating G_SEQUENCE in the ARM backend and remove the code dealing with it. This boils down to the code breaking up double values for the soft float calling convention. Use G_MERGE_VALUES + G_UNMERGE_VALUES instead of G_SEQUENCE + G_EXTRACT for it. This maps very nicely to VMOVDRR + VMOVRRD and simplifies the code in the instruction selector. There's one occurence of G_SEQUENCE left in arm-irtranslator.ll, but that is part of the target-independent code for translating constant structs. Therefore, it is beyond the scope of this commit. llvm-svn: 304902
* Reland r303247: [ARM] GlobalISel: Remove dead instruction selection codeDiana Picus2017-05-171-15/+0
| | | | | | | | It only failed on llvm-clang-x86_64-expensive-checks-win, probably because the TableGen stuff hasn't been regenerated. Requires a clean build. llvm-svn: 303252
* Revert "[ARM] GlobalISel: Remove dead instruction selection code"Diana Picus2017-05-171-0/+15
| | | | | | | This reverts commit r303247 because the tests are failing on some bots. Sorry! llvm-svn: 303249
* [ARM] GlobalISel: Remove dead instruction selection codeDiana Picus2017-05-171-15/+0
| | | | | | | We can now generate code for selecting G_ADD, G_SUB and G_MUL. Remove the hand-written versions. llvm-svn: 303247
* [ARM][GlobalISel] Support for G_ANYEXTDiana Picus2017-05-111-10/+3
| | | | | | | | | | | | | | G_ANYEXT can be introduced by the legalizer when widening scalars. Add support for it in the register bank info (same mapping as everything else) and in the instruction selector. When selecting it, we treat it as a COPY, just like G_TRUNC. On this occasion we get rid of some assertions in selectCopy so we can reuse it. This shouldn't be a problem at the moment since we're not supporting any complicated cases (e.g. FPR, different register banks). We might want to separate the paths when we do. llvm-svn: 302778
* [ARM GlobalISel] Remove hand-written G_FADD selectionDiana Picus2017-05-091-26/+0
| | | | | | | Remove the code selecting G_FADD - now that TableGen can handle more opcodes, it's not needed anymore. llvm-svn: 302511
* [ARM] GlobalISel: Use TableGen instruction selectorDiana Picus2017-05-021-15/+43
| | | | | | | | | | | Emit and use the TableGen instruction selector for ARM. At the moment, this allows us to remove the hand-written code for selecting G_SDIV and G_UDIV. Future commits will focus on increasing the code coverage for it and removing more dead code from the current instruction selector. llvm-svn: 301905
* [ARM] GlobalISel: Get rid of ARMInstructionSelector.h. NFC.Diana Picus2017-04-281-1/+24
| | | | | | | | | Declare the ARMInstructionSelector in an anonymous namespace, to make it more in line with the other targets which were migrated to this in r299637 in order to avoid TableGen'erated headers being included in non-GlobalISel builds. llvm-svn: 301632
* [ARM] GlobalISel: Support G_(S|U)DIV for s32Diana Picus2017-04-241-0/+10
| | | | | | | | | Add support for both targets with hardware division and without. For hardware division we have to add support throughout the pipeline (legalizer, reg bank select, instruction select). For targets without hardware division, we only need to mark it as a libcall. llvm-svn: 301164
* [ARM] GlobalISel: Select G_CONSTANT with CImm operandsDiana Picus2017-04-241-0/+12
| | | | | | | | | | | | | | When selecting a G_CONSTANT to a MOVi, we need the value to be an Imm operand. We used to just leave the G_CONSTANT operand unchanged, which works in some cases (such as the GEP offsets that we create when referring to stack slots). However, in many other places the G_CONSTANTs are created with CImm operands. This patch makes sure to handle those as well, and to error out gracefully if in the end we don't end up with an Imm operand. Thanks to Oliver Stannard for reporting this issue. llvm-svn: 301162
* [ARM] GlobalISel: Add support for G_TRUNCDiana Picus2017-04-211-6/+25
| | | | | | | | Select them as copies. We only select if both the source and the destination are on the same register bank, so this shouldn't cause any trouble. llvm-svn: 300971
* [ARM] GlobalISel: Add support for G_MULDiana Picus2017-04-191-0/+10
| | | | | | | | Support G_MUL, very similar to G_ADD and G_SUB. The only difference is in the instruction selector, where we have to select either MUL or MULv5 depending on the target. llvm-svn: 300665
* [ARM] GlobalISel: Add support for G_SUBDiana Picus2017-04-181-0/+4
| | | | | | | Support G_SUB throughout the GlobalISel pipeline. It is exactly the same as G_ADD, nothing fancy. llvm-svn: 300546
* GlobalISel: restrict G_EXTRACT instruction to just one operand.Tim Northover2017-03-061-12/+8
| | | | | | | A bit more painful than G_INSERT because it was more widely used, but this should simplify the handling of extract operations in most locations. llvm-svn: 297100
* [ARM] GlobalISel: Select 32-bit G_CONSTANTDiana Picus2017-02-281-0/+11
| | | | | | Put it into a register by means of a MOVi. llvm-svn: 296471
* [ARM] GlobalISel: Select G_GEPDiana Picus2017-02-281-0/+1
| | | | | | At this point, G_GEP is just an add, so we treat it exactly like a G_ADD. llvm-svn: 296462
* [ARM] GlobalISel: Select G_STOREDiana Picus2017-02-241-16/+20
| | | | | | Same as selecting G_LOAD. llvm-svn: 296122
* [ARM] GlobalISel: Don't select atomic loadsDiana Picus2017-02-201-0/+6
| | | | | | | | | | | | | | | There used to be a check in the IRTranslator that prevented us from having to deal with atomic loads/stores. That check has been removed in r294993 and the AArch64 backend was updated accordingly. This commit does the same thing for the ARM backend. In general, in the ARM backend we introduce fences during the atomic expand pass, so we don't have to worry about atomics, *except* for the 32-bit ARMv8 target, which handles atomics more like AArch64. Since we don't want to worry about that yet, just bail out of instruction selection if we find any atomic loads. llvm-svn: 295662
* [ARM] GlobalISel: Clean up some helpersDiana Picus2017-02-171-19/+24
| | | | | | | Return invalid opcodes when some of the helpers in the instruction selection pass can't handle a given combination. llvm-svn: 295446
* [ARM] GlobalISel: Select floating point loadsDiana Picus2017-02-161-10/+31
| | | | llvm-svn: 295321
* [ARM] GlobalISel: Select G_SEQUENCE and G_EXTRACTDiana Picus2017-02-161-0/+78
| | | | | | | | Since they're only used for passing around double precision floating point values into the general purpose registers, we'll lower them to VMOVDRR and VMOVRRD. llvm-svn: 295310
* [ARM] GlobalISel: Select double G_FADD and copiesDiana Picus2017-02-161-6/+29
| | | | | | Just use VADDD if available, bail out if not. llvm-svn: 295309
* [ARM] GlobalISel: Add FPR reg bankDiana Picus2017-02-081-1/+16
| | | | | | | | | | | | | Add a register bank for floating point values and select simple instructions using them (add, copies from GPR). This assumes that the hardware can cope with a single precision add (VADDS) instruction, so the legalizer will treat G_FADD as legal and the instruction selector will refuse to select if the hardware doesn't support it. In the future we'll want to be more careful about this, and legalize to libcalls if we have to use soft float. llvm-svn: 294442
* [ARM] GlobalISel: Load i1, i8 and i16 args from stackDiana Picus2017-01-261-2/+30
| | | | | | | | | | | | | Add support for loading i1, i8 and i16 arguments from the stack, with or without the ABI extension flags. When the ABI extension flags are present, we load a 4-byte value, otherwise we preserve the size of the load and let the instruction selector replace it with a LDRB/LDRH. This generates the same thing as DAGISel. Differential Revision: https://reviews.llvm.org/D27803 llvm-svn: 293163
* [ARM] GlobalISel: Fix stack-use-after-scope bug.Martin Bohme2017-01-251-1/+1
| | | | | | | | | | | | | | | | | Summary: Lifetime extension wasn't triggered on the result of BuildMI because the reference was non-const. However, instead of adding a const, I've removed the reference entirely as RVO should kick in anyway. Reviewers: rovka, bkramer Reviewed By: bkramer Subscribers: aemerson, rengolin, dberris, llvm-commits, kristof.beyls Differential Revision: https://reviews.llvm.org/D29124 llvm-svn: 293059
* [ARM] GlobalISel: Support i1 add and ABI extensionsDiana Picus2017-01-251-0/+28
| | | | | | | | | | | Add support for: * i1 add * i1 function arguments, if passed through registers * i1 returns, with ABI signext/zeroext Differential Revision: https://reviews.llvm.org/D27706 llvm-svn: 293035
* [ARM] GlobalISel: Support i8/i16 ABI extensionsDiana Picus2017-01-251-0/+42
| | | | | | | | | | | | | At the moment, this means supporting the signext/zeroext attribute on the return type of the function. For function arguments, signext/zeroext should be handled by the caller, so there's nothing for us to do until we start lowering calls. Note that this does not include support for other extensions (i8 to i16), those will be added later. Differential Revision: https://reviews.llvm.org/D27705 llvm-svn: 293034
* [ARM] CodeGen: Remove AddDefaultCC. NFC.Diana Picus2017-01-131-2/+2
| | | | | | | | | | Replace all uses of AddDefaultCC with add(condCodeOp()). The transformation has been done automatically with a custom tool based on Clang AST Matchers + RefactoringTool. Differential Revision: https://reviews.llvm.org/D28557 llvm-svn: 291893
* [ARM] CodeGen: Remove AddDefaultPred. NFC.Diana Picus2017-01-131-3/+3
| | | | | | | | | | | | | | | | | | | | | | | | | Replace all uses of AddDefaultPred with MachineInstrBuilder::add(predOps()). This makes the code building MachineInstrs more readable, because it allows us to write code like: MIB.addSomeOperand(blah) .add(predOps()) .addAnotherOperand(blahblah) instead of AddDefaultPred(MIB.addSomeOperand(blah)) .addAnotherOperand(blahblah) This commit also adds the predOps helper in the ARM backend, as well as the add method taking a variable number of operands to the MachineInstrBuilder. The transformation has been done mostly automatically with a custom tool based on Clang AST Matchers + RefactoringTool. Differential Revision: https://reviews.llvm.org/D28555 llvm-svn: 291890
* Silence unused warning.Daniel Jasper2016-12-191-0/+1
| | | | llvm-svn: 290109
* [ARM] GlobalISel: Select i8 and i16 copiesDiana Picus2016-12-191-2/+9
| | | | | | | | | Teach the instruction selector that it's ok to copy small values from physical registers. First part of https://reviews.llvm.org/D27704 llvm-svn: 290104
* [ARM] GlobalISel: Support loading from the stackDiana Picus2016-12-191-4/+20
| | | | | | | | | | Add support for selecting simple G_LOAD and G_FRAME_INDEX instructions (32-bit scalars only). This will be useful for functions that need to pass arguments on the stack. First part of https://reviews.llvm.org/D27195. llvm-svn: 290096
* [GlobalISel] Silence unused variable warnings in Release builds.Benjamin Kramer2016-12-161-5/+4
| | | | llvm-svn: 289941
* [ARM] GlobalISel: Select add i32, i32Diana Picus2016-12-161-3/+54
| | | | | | | | | | | | | Add the minimal support necessary to select a function that returns the sum of two i32 values. This includes some support for argument/return lowering of i32 values through registers, as well as the handling of copy and add instructions throughout the GlobalISel pipeline. Differential Revision: https://reviews.llvm.org/D26677 llvm-svn: 289940
* GlobalISel: remove unused variable to silence warning.Tim Northover2016-11-151-1/+1
| | | | llvm-svn: 287027
* [ARM] GlobalISel: Remove unused members. NFCIDiana Picus2016-11-151-3/+2
| | | | | | This silences some warnings that I didn't see with my host compiler. llvm-svn: 286981
* [ARM] Add plumbing for GlobalISelDiana Picus2016-11-111-0/+36
Add GlobalISel skeleton, up to the point where we can select a ret void. llvm-svn: 286573
OpenPOWER on IntegriCloud