llvm-project/llvm/lib/Target/AMDGPU
Sanjay Patel 0a515595a7 [x86] allow vector load narrowing with multi-use values
This is a long-awaited follow-up suggested in D33578. Since then, we've picked up even more
opportunities for vector narrowing from changes like D53784, so there are a lot of test diffs.
Apart from 2-3 strange cases, these are all wins.

I've structured this to be no-functional-change-intended for any target except for x86
because I couldn't tell if AArch64, ARM, and AMDGPU would improve or not. All of those
targets have existing regression tests (4, 4, 10 files respectively) that would be
affected. Also, Hexagon overrides the shouldReduceLoadWidth() hook, but doesn't show
any regression test diffs. The trade-off is deciding if an extra vector load is better
than a single wide load + extract_subvector.

For x86, this is almost always better (on paper at least) because we often can fold
loads into subsequent ops and not increase the official instruction count. There's also
some unknown -- but potentially large -- benefit from using narrower vector ops if wide
ops are implemented with multiple uops and/or frequency throttling is avoided.

Differential Revision: https://reviews.llvm.org/D54073

llvm-svn: 346595
2018-11-10 20:05:31 +00:00
..
AsmParser AMDGPU: Re-apply r341982 after fixing the layering issue 2018-09-12 18:50:47 +00:00
Disassembler AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
InstPrinter AMDGPU: Re-apply r341982 after fixing the layering issue 2018-09-12 18:50:47 +00:00
MCTargetDesc AMDGPU: Add sram-ecc feature 2018-11-05 22:44:19 +00:00
TargetInfo Remove \brief commands from doxygen comments. 2018-05-01 15:54:18 +00:00
Utils Revert "AMDGPU: Divergence-driven selection of scalar buffer load intrinsics" 2018-11-07 21:53:43 +00:00
AMDGPU.h Allow subclassing ExternalAA 2018-11-07 20:26:42 +00:00
AMDGPU.td AMDGPU: Add sram-ecc feature 2018-11-05 22:44:19 +00:00
AMDGPUAliasAnalysis.cpp Allow subclassing ExternalAA 2018-11-07 20:26:42 +00:00
AMDGPUAliasAnalysis.h Allow subclassing ExternalAA 2018-11-07 20:26:42 +00:00
AMDGPUAlwaysInlinePass.cpp AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUAnnotateKernelFeatures.cpp AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUAnnotateUniformValues.cpp AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUArgumentUsageInfo.cpp AMDGPU/AMDHSA: Remove GridWorkGroupCountX/Y/Z 2018-06-21 18:36:04 +00:00
AMDGPUArgumentUsageInfo.h AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
AMDGPUAsmPrinter.cpp [AMDGPU] Remove FeatureVGPRSpilling 2018-10-31 18:54:06 +00:00
AMDGPUAsmPrinter.h AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUAtomicOptimizer.cpp [AMDGPU] Fix the new atomic optimizer in pixel shaders. 2018-11-05 12:04:48 +00:00
AMDGPUCallLowering.cpp AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUCallLowering.h AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUCallingConv.td AMDGPU: Partially fix handling of packed amdgpu_ps arguments 2018-08-01 19:57:34 +00:00
AMDGPUCodeGenPrepare.cpp [IRBuilder] Fixup CreateIntrinsic to allow specifying Types to Mangle. 2018-10-08 10:32:33 +00:00
AMDGPUFeatures.td AMDGPU: Allow fp32-denormals feature for r600 targets 2018-08-01 15:04:36 +00:00
AMDGPUFixFunctionBitcasts.cpp [AMDGPU] Add a pass to promote bitcast calls 2018-10-26 13:18:36 +00:00
AMDGPUFrameLowering.cpp
AMDGPUFrameLowering.h Remove \brief commands from doxygen comments. 2018-05-01 15:54:18 +00:00
AMDGPUGISel.td AMDGPU/GlobalISel: Select amdgcn.cvt.pkrtz to 64-bit instructions 2018-10-08 17:49:29 +00:00
AMDGPUGenRegisterBankInfo.def AMDGPU/GlobalISel: Fix crash in regbankselect on non-power-of-2 types 2018-07-27 06:04:40 +00:00
AMDGPUHSAMetadataStreamer.cpp AMDGPU: Don't abort on unknown addrspace argument 2018-09-10 02:23:30 +00:00
AMDGPUHSAMetadataStreamer.h AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUISelDAGToDAG.cpp AMDGPU: Avoid selecting ds_{read,write}2_b32 on SI 2018-10-17 15:37:48 +00:00
AMDGPUISelLowering.cpp [x86] allow vector load narrowing with multi-use values 2018-11-10 20:05:31 +00:00
AMDGPUISelLowering.h DAG: Change behavior of fminnum/fmaxnum nodes 2018-10-22 16:27:27 +00:00
AMDGPUInline.cpp fix typos aggressively; NFC 2018-11-07 14:35:36 +00:00
AMDGPUInstrInfo.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
AMDGPUInstrInfo.h AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
AMDGPUInstrInfo.td AMDGPU: Remove PHI loop condition optimization 2018-10-31 13:26:48 +00:00
AMDGPUInstructionSelector.cpp Revert "AMDGPU/GlobalISel: Implement select for G_INSERT" 2018-10-11 23:36:46 +00:00
AMDGPUInstructionSelector.h Revert "AMDGPU/GlobalISel: Implement select for G_INSERT" 2018-10-11 23:36:46 +00:00
AMDGPUInstructions.td DAG: Change behavior of fminnum/fmaxnum nodes 2018-10-22 16:27:27 +00:00
AMDGPUIntrinsicInfo.cpp [AMDGPU] Update includes for intrinsic changes :( 2018-06-23 03:05:39 +00:00
AMDGPUIntrinsicInfo.h [AMDGPU] Update includes for intrinsic changes :( 2018-06-23 03:05:39 +00:00
AMDGPUIntrinsics.td AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
AMDGPULegalizerInfo.cpp AMDGPU/GlobalISel: Add support for G_INTTOPTR 2018-10-05 04:34:09 +00:00
AMDGPULegalizerInfo.h AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
AMDGPULibCalls.cpp AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPULibFunc.cpp [cxx2a] Fix warning triggered by r343285 2018-09-29 02:17:12 +00:00
AMDGPULibFunc.h AMDGPU: Fix missing C++ mode comment 2018-06-20 19:45:40 +00:00
AMDGPULowerIntrinsics.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
AMDGPULowerKernelArguments.cpp [IRBuilder] Fixup CreateIntrinsic to allow specifying Types to Mangle. 2018-10-08 10:32:33 +00:00
AMDGPULowerKernelAttributes.cpp AMDGPU: Add pass to optimize reqd_work_group_size 2018-05-18 21:35:00 +00:00
AMDGPUMCInstLower.cpp AMDGPU: Fix getInstSizeInBytes 2018-08-29 07:46:09 +00:00
AMDGPUMachineCFGStructurizer.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
AMDGPUMachineFunction.cpp Reapply "AMDGPU: Fix handling of alignment padding in DAG argument lowering" 2018-07-20 09:05:08 +00:00
AMDGPUMachineFunction.h Reapply "AMDGPU: Fix handling of alignment padding in DAG argument lowering" 2018-07-20 09:05:08 +00:00
AMDGPUMachineModuleInfo.cpp Remove \brief commands from doxygen comments. 2018-05-01 15:54:18 +00:00
AMDGPUMachineModuleInfo.h Remove \brief commands from doxygen comments. 2018-05-01 15:54:18 +00:00
AMDGPUMacroFusion.cpp [AMDGPU] Always pass TRI into findRegister[Use/Def]OperandIdx 2018-11-09 17:58:59 +00:00
AMDGPUMacroFusion.h
AMDGPUOpenCLEnqueuedBlockLowering.cpp [AMDGPU] Change enqueue kernel handle type 2018-06-13 17:31:51 +00:00
AMDGPUPTNote.h AMDGPU/NFC: Move AMDGPU specific note types to ELF.h 2017-10-12 18:59:54 +00:00
AMDGPUPerfHintAnalysis.cpp AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUPerfHintAnalysis.h Fix -Winconsistent-missing-overrides in AMDGPU code 2018-05-25 17:46:24 +00:00
AMDGPUPromoteAlloca.cpp [AMDGPU] Extend promote alloca vectorization 2018-11-08 00:16:23 +00:00
AMDGPURegAsmNames.inc.cpp
AMDGPURegisterBankInfo.cpp Fix clang -Wimplicit-fallthrough warnings across llvm, NFC 2018-11-01 19:54:45 +00:00
AMDGPURegisterBankInfo.h AMDGPU/GlobalISel: Define instruction mapping for G_OR 2018-03-01 21:25:25 +00:00
AMDGPURegisterBanks.td AMDGPU/GlobalISel: Define InstrMappings for G_ICMP 2018-03-01 19:27:10 +00:00
AMDGPURegisterInfo.cpp AMDGPU: Remove #include "MCTargetDesc/AMDGPUMCTargetDesc.h" from common headers 2018-05-22 02:03:23 +00:00
AMDGPURegisterInfo.h [TargetRegisterInfo] Remove temporary hook enableMultipleCopyHints() 2018-10-05 14:23:11 +00:00
AMDGPURegisterInfo.td AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
AMDGPURewriteOutArguments.cpp Rename DEBUG macro to LLVM_DEBUG. 2018-05-14 12:53:11 +00:00
AMDGPUSearchableTables.td AMDGPU: Remove old-style image intrinsics 2018-06-21 13:37:45 +00:00
AMDGPUSubtarget.cpp AMDGPU: Add sram-ecc feature 2018-11-05 22:44:19 +00:00
AMDGPUSubtarget.h AMDGPU: Add sram-ecc feature 2018-11-05 22:44:19 +00:00
AMDGPUTargetMachine.cpp Allow subclassing ExternalAA 2018-11-07 20:26:42 +00:00
AMDGPUTargetMachine.h AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUTargetObjectFile.cpp AMDGPU: Fix set but not used warnings related to AMDGPUAS 2017-11-01 19:12:38 +00:00
AMDGPUTargetObjectFile.h Remove \brief commands from doxygen comments. 2018-05-01 15:54:18 +00:00
AMDGPUTargetTransformInfo.cpp AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUTargetTransformInfo.h AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
AMDGPUUnifyDivergentExitNodes.cpp [NFC] Rename the DivergenceAnalysis to LegacyDivergenceAnalysis 2018-08-30 14:21:36 +00:00
AMDGPUUnifyMetadata.cpp Remove \brief commands from doxygen comments. 2018-05-01 15:54:18 +00:00
AMDILCFGStructurizer.cpp AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
AMDKernelCodeT.h Remove @brief commands from doxygen comments, too. 2018-05-01 16:10:38 +00:00
BUFInstructions.td AMDGPU/NFC: Split MUBUF_Pseudo_Atomics into RTN/NO_RTN multiclasses 2018-11-07 21:21:32 +00:00
CMakeLists.txt [AMDGPU] Add a pass to promote bitcast calls 2018-10-26 13:18:36 +00:00
CaymanInstructions.td [CodeGen] Use MachineOperand::print in the MIRPrinter for MO_Register. 2017-12-07 10:40:31 +00:00
DSInstructions.td AMDGPU: Avoid selecting ds_{read,write}2_b32 on SI 2018-10-17 15:37:48 +00:00
EvergreenInstructions.td AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
FLATInstructions.td AMDGPU/NFC: Split FLAT_Global_Atomic_Pseudo into RTN/NO_RTN multiclasses 2018-11-07 21:42:13 +00:00
GCNHazardRecognizer.cpp [AMDGPU] Prevent sequences of non-instructions disrupting GCNHazardRecognizer wait state counting 2018-09-10 10:14:48 +00:00
GCNHazardRecognizer.h AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
GCNILPSched.cpp ScheduleDAG: Cleanup dumping code; NFC 2018-09-19 00:23:35 +00:00
GCNIterativeScheduler.cpp llvm::sort(C.begin(), C.end(), ...) -> llvm::sort(C, ...) 2018-09-27 02:13:45 +00:00
GCNIterativeScheduler.h AMDGPU: Partial ILP scheduler port from SelectionDAG to SchedulingDAG (experimental) 2017-11-20 14:35:53 +00:00
GCNMinRegStrategy.cpp ScheduleDAG: Cleanup dumping code; NFC 2018-09-19 00:23:35 +00:00
GCNProcessors.td [AMDGPU] Defined gfx909 Raven Ridge 2 2018-10-24 08:14:07 +00:00
GCNRegPressure.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
GCNRegPressure.h AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
GCNSchedStrategy.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
GCNSchedStrategy.h AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
LLVMBuild.txt
MIMGInstructions.td [AMDGPU] Add support for a16 modifiear for gfx9 2018-08-28 15:07:30 +00:00
R600.td Reapply "AMDGPU: Fix handling of alignment padding in DAG argument lowering" 2018-07-20 09:05:08 +00:00
R600AsmPrinter.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
R600AsmPrinter.h AMDGPU: Split R600 AsmPrinter code into its own class 2018-05-24 20:02:01 +00:00
R600ClauseMergePass.cpp AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
R600ControlFlowFinalizer.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
R600Defines.h Remove \brief commands from doxygen comments. 2018-05-01 15:54:18 +00:00
R600EmitClauseMarkers.cpp [AMDGPU] Always pass TRI into findRegister[Use/Def]OperandIdx 2018-11-09 17:58:59 +00:00
R600ExpandSpecialInstrs.cpp AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
R600FrameLowering.cpp
R600FrameLowering.h
R600ISelLowering.cpp [SelectionDAG] Add FoldBUILD_VECTOR to simplify new BUILD_VECTOR nodes 2018-10-30 10:32:11 +00:00
R600ISelLowering.h AMDGPU/R600: Convert kernel param loads to use PARAM_I_ADDRESS 2018-08-01 18:36:07 +00:00
R600InstrFormats.td AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
R600InstrInfo.cpp [AMDGPU] Always pass TRI into findRegister[Use/Def]OperandIdx 2018-11-09 17:58:59 +00:00
R600InstrInfo.h [PSV] Update API to be able to use TargetCustom without UB. 2018-08-20 19:23:45 +00:00
R600Instructions.td AMDGPU: Remove remnants of old address space mapping 2018-08-31 05:49:54 +00:00
R600MachineFunctionInfo.cpp
R600MachineFunctionInfo.h
R600MachineScheduler.cpp Fix clang -Wimplicit-fallthrough warnings across llvm, NFC 2018-11-01 19:54:45 +00:00
R600MachineScheduler.h Remove \brief commands from doxygen comments. 2018-05-01 15:54:18 +00:00
R600OpenCLImageTypeLoweringPass.cpp AMDGPU: Rename OpenCL lowering pass to be R600 specific. 2018-05-13 10:04:48 +00:00
R600OptimizeVectorRegisters.cpp AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
R600Packetizer.cpp AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
R600Processors.td AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
R600RegisterInfo.cpp AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
R600RegisterInfo.h AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
R600RegisterInfo.td AMDGPU: Separate R600 and GCN TableGen files 2018-06-28 23:47:12 +00:00
R600Schedule.td
R700Instructions.td AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
SIAnnotateControlFlow.cpp AMDGPU: Remove PHI loop condition optimization 2018-10-31 13:26:48 +00:00
SIDebuggerInsertNops.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
SIDefines.h AMDGPU: Turn D16 for MIMG instructions into a regular operand 2018-06-21 13:36:01 +00:00
SIFixSGPRCopies.cpp AMDGPU: Rewrite SILowerI1Copies to always stay on SALU 2018-10-31 13:27:08 +00:00
SIFixVGPRCopies.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
SIFixWWMLiveness.cpp [AMDGPU] Reworked SIFixWWMLiveness 2018-08-02 23:31:32 +00:00
SIFoldOperands.cpp [AMDGPU] Fold copy (copy vgpr) 2018-09-27 18:55:20 +00:00
SIFormMemoryClauses.cpp llvm::sort(C.begin(), C.end(), ...) -> llvm::sort(C, ...) 2018-09-27 02:13:45 +00:00
SIFrameLowering.cpp AMDGPU: Rename isAmdCodeObjectV2 -> isAmdHsaOrMesa 2018-10-04 21:02:16 +00:00
SIFrameLowering.h AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
SIISelLowering.cpp Revert "AMDGPU: Divergence-driven selection of scalar buffer load intrinsics" 2018-11-07 21:53:43 +00:00
SIISelLowering.h Revert "AMDGPU: Divergence-driven selection of scalar buffer load intrinsics" 2018-11-07 21:53:43 +00:00
SIInsertSkips.cpp AMDGPU: Force skip over s_sendmsg and exp instructions 2018-07-30 09:23:59 +00:00
SIInsertWaitcnts.cpp AMDGPU/InsertWaitcnts: Cleanup some old cruft (NFCI) 2018-11-07 21:53:36 +00:00
SIInstrFormats.td AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
SIInstrInfo.cpp [AMDGPU] Always pass TRI into findRegister[Use/Def]OperandIdx 2018-11-09 17:58:59 +00:00
SIInstrInfo.h Revert "AMDGPU: Divergence-driven selection of scalar buffer load intrinsics" 2018-11-07 21:53:43 +00:00
SIInstrInfo.td [AMDGPU] Legalize VGPR Rsrc operands for MUBUF instructions 2018-10-08 18:47:01 +00:00
SIInstructions.td AMDGPU: Remove PHI loop condition optimization 2018-10-31 13:26:48 +00:00
SIIntrinsics.td
SILoadStoreOptimizer.cpp [AMDGPU] Fix ds combine with subregs 2018-09-25 23:33:18 +00:00
SILowerControlFlow.cpp AMDGPU: Remove PHI loop condition optimization 2018-10-31 13:26:48 +00:00
SILowerI1Copies.cpp AMDGPU: Rewrite SILowerI1Copies to always stay on SALU 2018-10-31 13:27:08 +00:00
SIMachineFunctionInfo.cpp [AMDGPU] Remove FeatureVGPRSpilling 2018-10-31 18:54:06 +00:00
SIMachineFunctionInfo.h AMDGPU/AMDHSA: Remove GridWorkGroupCountX/Y/Z 2018-06-21 18:36:04 +00:00
SIMachineScheduler.cpp ScheduleDAG: Cleanup dumping code; NFC 2018-09-19 00:23:35 +00:00
SIMachineScheduler.h Remove \brief commands from doxygen comments. 2018-05-01 15:54:18 +00:00
SIMemoryLegalizer.cpp AMDGPU: Re-apply r341982 after fixing the layering issue 2018-09-12 18:50:47 +00:00
SIOptimizeExecMasking.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
SIOptimizeExecMaskingPreRA.cpp AMDGPU: Don't delete instructions if S_ENDPGM has implicit uses 2018-08-28 18:55:55 +00:00
SIPeepholeSDWA.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
SIProgramInfo.h [AMDGPU] Refactor HSAMetadataStream::emitKernel (NFC) 2018-07-10 17:31:32 +00:00
SIRegisterInfo.cpp [MI] Change the array of `MachineMemOperand` pointers to be 2018-08-16 21:30:05 +00:00
SIRegisterInfo.h AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
SIRegisterInfo.td AMDGPU: Make v4i16/v4f16 legal 2018-06-15 15:15:46 +00:00
SISchedule.td [SchedModel] Complete models shouldn't match against itineraries when they don't use them (PR35639) 2018-04-05 13:11:36 +00:00
SIShrinkInstructions.cpp [AMDGPU] Fixed return value causing warning and regression 2018-10-29 17:53:23 +00:00
SIWholeQuadMode.cpp AMDGPU: Refactor Subtarget classes 2018-07-11 20:59:01 +00:00
SMInstructions.td AMDGPU: Consolidate SMRD TableGen patterns 2018-10-06 03:32:43 +00:00
SOPInstructions.td [AMDGPU] Divergence driven instruction selection. Shift operations. 2018-10-01 11:06:35 +00:00
VIInstrFormats.td
VIInstructions.td
VOP1Instructions.td AMDGPU: Split HasExt into HasExtDPP/SDWA/SDWA9 2018-09-27 20:49:00 +00:00
VOP2Instructions.td DAG: Change behavior of fminnum/fmaxnum nodes 2018-10-22 16:27:27 +00:00
VOP3Instructions.td DAG: Change behavior of fminnum/fmaxnum nodes 2018-10-22 16:27:27 +00:00
VOP3PInstructions.td [AMDGPU] Handle the idot8 pattern generated by FE. 2018-11-01 22:48:19 +00:00
VOPCInstructions.td AMDGPU: Implement llvm.amdgcn.icmp/fcmp for i16/f16 2018-08-15 21:25:20 +00:00
VOPInstructions.td [AMDGPU] Divergence driven instruction selection. Shift operations. 2018-10-01 11:06:35 +00:00