|
15 | 15 | */
|
16 | 16 | package de.mirkosertic.bytecoder.api.opencl;
|
17 | 17 |
|
| 18 | +import java.util.Comparator; |
| 19 | +import java.util.Objects; |
| 20 | +import java.util.function.Predicate; |
| 21 | + |
18 | 22 | public class OpenCLOptions {
|
19 | 23 |
|
20 |
| - private final boolean preferStackifier; |
| 24 | + public static enum CodeGeneratorStyle { |
| 25 | + |
| 26 | + /** |
| 27 | + * The Stackifier tries to remove all GOTO statements and |
| 28 | + * replaces them with structured control flow elements and multi level break and continues. |
| 29 | + * <p> |
| 30 | + * The Stackifier does only work for reducible control flows and also does not support |
| 31 | + * exception handling. The generated output is smaller and in some cases faster compared |
| 32 | + * to the Relooper output. |
| 33 | + */ |
| 34 | + STACKIFIER, |
| 35 | + |
| 36 | + /** |
| 37 | + * The Relooper output generator tries to recover high level control flow constructs |
| 38 | + * from the intermediate representation. This step eliminates the needs of GOTO |
| 39 | + * statements and thus allows generation of more natural source code, which in turn |
| 40 | + * can be easier read and optimized by Web Browsers or other tools. |
| 41 | + * <p> |
| 42 | + * The Relooper supports all styles of control flows and also supports exception handling. |
| 43 | + */ |
| 44 | + RELOOPER |
| 45 | + } |
| 46 | + |
| 47 | + private final CodeGeneratorStyle codeGeneratorStyle; |
| 48 | + public CodeGeneratorStyle getCodeGeneratorStyle() { |
| 49 | + return codeGeneratorStyle; |
| 50 | + } |
| 51 | + |
| 52 | + private final Predicate<PlatformProperties> platformFilter; |
| 53 | + public Predicate<PlatformProperties> getPlatformFilter() { |
| 54 | + return platformFilter; |
| 55 | + } |
| 56 | + |
| 57 | + private final Comparator<DeviceProperties> preferredDeviceComparator; |
| 58 | + public Comparator<DeviceProperties> getPreferredDeviceComparator() { |
| 59 | + return preferredDeviceComparator; |
| 60 | + } |
| 61 | + |
| 62 | + /** |
| 63 | + * @apiNote not exposed, use builder to create an instance |
| 64 | + */ |
| 65 | + private OpenCLOptions( |
| 66 | + final CodeGeneratorStyle codeGeneratorStyle, |
| 67 | + final Predicate<PlatformProperties> platformFilter, |
| 68 | + final Comparator<DeviceProperties> preferredDeviceComparator) { |
| 69 | + this.codeGeneratorStyle = codeGeneratorStyle; |
| 70 | + this.platformFilter = platformFilter; |
| 71 | + this.preferredDeviceComparator = preferredDeviceComparator; |
| 72 | + } |
21 | 73 |
|
| 74 | + /** |
| 75 | + * |
| 76 | + * @deprecated use {@link OpenCLOptions#builder()} instead. |
| 77 | + * |
| 78 | + */ |
| 79 | + @Deprecated |
22 | 80 | public OpenCLOptions(final boolean preferStackifier) {
|
23 |
| - this.preferStackifier = preferStackifier; |
| 81 | + this.codeGeneratorStyle = preferStackifier |
| 82 | + ? CodeGeneratorStyle.STACKIFIER |
| 83 | + : CodeGeneratorStyle.RELOOPER; |
| 84 | + final OpenCLOptions defaults = defaults(); |
| 85 | + this.platformFilter = defaults.getPlatformFilter(); |
| 86 | + this.preferredDeviceComparator = defaults.getPreferredDeviceComparator(); |
24 | 87 | }
|
25 | 88 |
|
26 | 89 | public boolean isPreferStackifier() {
|
27 |
| - return preferStackifier; |
| 90 | + return codeGeneratorStyle == CodeGeneratorStyle.STACKIFIER; |
| 91 | + } |
| 92 | + |
| 93 | + // -- DEFAULTS |
| 94 | + |
| 95 | + public static OpenCLOptions defaults() { |
| 96 | + return OpenCLOptions.builder().build(); |
28 | 97 | }
|
| 98 | + |
| 99 | + // -- OPTIONS BUILDER |
| 100 | + |
| 101 | + public static final class OpenCLOptionsBuilder { |
| 102 | + private CodeGeneratorStyle codeGeneratorStyle = CodeGeneratorStyle.STACKIFIER; |
| 103 | + private Predicate<PlatformProperties> platformFilter = p -> true; |
| 104 | + private Comparator<DeviceProperties> preferredDeviceComparator = (a, b) -> Integer.compare( |
| 105 | + a.getNumberOfComputeUnits(), |
| 106 | + b.getNumberOfComputeUnits()); |
| 107 | + |
| 108 | + /** |
| 109 | + * There are different output styles available for generated code. |
| 110 | + * @param codeGeneratorStyle |
| 111 | + */ |
| 112 | + public OpenCLOptionsBuilder codeGeneratorStyle(CodeGeneratorStyle codeGeneratorStyle) { |
| 113 | + Objects.requireNonNull(codeGeneratorStyle); |
| 114 | + this.codeGeneratorStyle = codeGeneratorStyle; |
| 115 | + return this; |
| 116 | + } |
| 117 | + |
| 118 | + /** |
| 119 | + * Platforms are rejected if the platformFilter predicate returns false. |
| 120 | + * @param platformFilter |
| 121 | + */ |
| 122 | + public OpenCLOptionsBuilder platformFilter(Predicate<PlatformProperties> platformFilter) { |
| 123 | + Objects.requireNonNull(platformFilter); |
| 124 | + this.platformFilter = platformFilter; |
| 125 | + return this; |
| 126 | + } |
| 127 | + |
| 128 | + /** |
| 129 | + * The device that compares highest is chosen by the {@link PlatformFactory}, unless explicitly |
| 130 | + * overridden by system property {@code OPENCL_DEVICE}. |
| 131 | + * @param preferredPlatformComparator |
| 132 | + */ |
| 133 | + public OpenCLOptionsBuilder preferredDeviceComparator(Comparator<DeviceProperties> preferredDeviceComparator) { |
| 134 | + Objects.requireNonNull(preferredDeviceComparator); |
| 135 | + this.preferredDeviceComparator = preferredDeviceComparator; |
| 136 | + return this; |
| 137 | + } |
| 138 | + |
| 139 | + public OpenCLOptions build() { |
| 140 | + return new OpenCLOptions(codeGeneratorStyle, platformFilter, preferredDeviceComparator); |
| 141 | + } |
| 142 | + } |
| 143 | + |
| 144 | + public static OpenCLOptionsBuilder builder() { |
| 145 | + return new OpenCLOptionsBuilder(); |
| 146 | + } |
| 147 | + |
| 148 | + |
| 149 | + |
29 | 150 | }
|
0 commit comments